Exemple #1
0
    def VE(self, data=None):
        """
        Version
        If data is None then sends the version & genesis_prev_headerhash.
        Otherwise, process the content of data and incase of non matching,
        genesis_prev_headerhash, it disconnects the odd peer.
        :return:
        """
        if not data:
            version_details = {
                'version': config.dev.version_number,
                'genesis_prev_headerhash': config.dev.genesis_prev_headerhash
            }
            self.transport.write(self.wrap_message('VE', helper.json_encode(version_details)))
        else:
            try:
                data = helper.json_decode(data)
                self.version = str(data['version'])
                logger.info('%s version: %s | genesis prev_headerhash %s',
                            self.transport.getPeer().host,
                            data['version'],
                            data['genesis_prev_headerhash'])

                if data['genesis_prev_headerhash'] == config.dev.genesis_prev_headerhash:
                    return
                logger.warning('%s genesis_prev_headerhash mismatch', self.conn_identity)
                logger.warning('Expected: %s', config.dev.genesis_prev_headerhash)
                logger.warning('Found: %s', data['genesis_prev_headerhash'])
            except Exception as e:
                logger.error('Peer Caused Exception %s', self.conn_identity)
                logger.exception(e)

            self.transport.loseConnection()

        return
Exemple #2
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
Exemple #3
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
Exemple #4
0
    def VE(self, data=None):
        if not data:
            version_details = {
                'version': config.dev.version_number,
                'genesis_prev_headerhash': config.dev.genesis_prev_headerhash
            }
            self.transport.write(
                self.wrap_message('VE', helper.json_encode(version_details)))
        else:
            try:
                data = helper.json_decode(data)
                self.version = str(data['version'])
                logger.info('%s version: %s | genesis prev_headerhash %s',
                            self.transport.getPeer().host, data['version'],
                            data['genesis_prev_headerhash'])

                if data['genesis_prev_headerhash'] == config.dev.genesis_prev_headerhash:
                    return
                logger.warning('%s genesis_prev_headerhash mismatch',
                               self.identity)
                logger.warning('Expected: ',
                               config.dev.genesis_prev_headerhash)
                logger.warning('Found: ', data['genesis_prev_headerhash'])
            except Exception as e:
                logger.error('Peer Caused Exception %s', self.identity)
                logger.exception(e)

            self.transport.loseConnection()

        return
Exemple #5
0
    def broadcast(self, msg_hash, msg_type):  # Move to factory
        data = {'hash': sha256(str(msg_hash)), 'type': msg_type}

        for peer in self.factory.peer_connections:
            if peer not in self.factory.master_mr.hash_peer[data['hash']]:
                peer.transport.write(
                    self.wrap_message('MR', helper.json_encode(data)))
Exemple #6
0
 def get_peers(self):
     logger.info('<<<Sending connected peers to %s',
                 self.transport.getPeer().host)
     peers_list = []
     for peer in self.factory.peer_connections:
         peers_list.append(peer.transport.getPeer().host)
     self.transport.write(
         self.wrap_message('PL', helper.json_encode(peers_list)))
     return
Exemple #7
0
    def register_and_broadcast(self, msg_type, msg_hash, msg_json):
        # FIXME: Try to keep parameters in the same order (consistency)
        self.master_mr.register(msg_hash, msg_json, msg_type)

        msg_hash = sha256(str(msg_hash))
        data = {'hash': msg_hash, 'type': msg_type}

        for peer in self.peer_connections:
            if msg_hash in self.master_mr.hash_peer:
                if peer in self.master_mr.hash_peer[msg_hash]:
                    continue
            peer.transport.write(self.f_wrap_message('MR', json_encode(data)))
Exemple #8
0
    def send_m_blockheight_to_peer(self):
        z = {
            'headerhash':
            self.factory.chain.m_blockchain[-1].blockheader.headerhash,
            'block_number': 0
        }

        if len(self.factory.chain.m_blockchain):
            z['block_number'] = self.factory.chain.m_blockchain[
                -1].blockheader.blocknumber
        self.transport.write(self.wrap_message('CB', helper.json_encode(z)))
        return
Exemple #9
0
 def FMBH(self):  # Fetch Maximum Blockheight and Headerhash
     if self.factory.pos.nodeState.state != NState.synced:
         return
     logger.info('<<<Sending blockheight and headerhash to: %s %s',
                 self.transport.getPeer().host, str(time.time()))
     data = {
         'headerhash':
         self.factory.chain.m_blockchain[-1].blockheader.headerhash,
         'blocknumber':
         self.factory.chain.m_blockchain[-1].blockheader.blocknumber
     }
     self.transport.write(
         self.wrap_message('PMBH', helper.json_encode(data)))
Exemple #10
0
    def send_tx(self, wallet_from, wallet_to, amount_arg):
        fee_arg = 0  # FIXME: Fee argument is missing here, the class will be removed. No plans for fixing this

        self.txnResult = {
            'status': 'fail',
            'message': '',
            'txnhash': '',
            'from': wallet_from,
            'to': wallet_to,
            'amount': amount_arg
        }

        qrlnode = self.qrlnode

        ########################
        ########################

        try:
            wallet_from = qrlnode.get_wallet_absolute(wallet_from)
            wallet_to = qrlnode.get_wallet_absolute(wallet_to)
            amount = qrlnode.get_dec_amount(amount_arg)
            fee = qrlnode.get_dec_amount(fee_arg)

            tx = qrlnode.transfer_coins(wallet_from, wallet_to, amount, fee)

        except Exception as e:
            self.txnResult["message"] = str(e)
            return bytes(helper.json_encode(self.txnResult), 'utf-8')

        ################################
        ################################

        self.txnResult["status"] = "success"
        self.txnResult["txnhash"] = str(tx.txhash)
        self.txnResult["from"] = str(tx.txfrom)
        self.txnResult["to"] = str(tx.txto)
        # FIXME: Magic number? Unify
        self.txnResult["amount"] = str(tx.amount / 100000000.000000000)
        return bytes(helper.json_encode(self.txnResult), 'utf-8')
Exemple #11
0
    def send_m_blockheight_to_peer(self):
        """
        Send mainchain blockheight to peer
        Sends the mainchain maximum blockheight request.
        :return:
        """
        z = {'headerhash': self.factory.chain.m_blockchain[-1].blockheader.headerhash,
             'block_number': 0}

        if len(self.factory.chain.m_blockchain):
            z['block_number'] = self.factory.chain.m_blockchain[-1].blockheader.blocknumber
        self.transport.write(self.wrap_message('CB', helper.json_encode(z)))
        return
Exemple #12
0
    def FMBH(self):  # Fetch Maximum Blockheight and Headerhash
        """
        Fetch Maximum Blockheight and HeaderHash
        Serves the fetch request for maximum blockheight & headerhash
        Sends the current blockheight and the headerhash of the 
        last block in mainchain.
        :return:
        """
        if self.factory.pos.nodeState.state != NState.synced:
            return
        logger.info('<<<Sending blockheight and headerhash to: %s %s', self.transport.getPeer().host, str(time.time()))

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

        self.transport.write(self.wrap_message('PMBH', helper.json_encode(data)))
        return
Exemple #13
0
    def broadcast(self, msg_hash, msg_type, data=None):  # Move to factory
        """
        Broadcast
        This function sends the Message Receipt to all connected peers.
        :return:
        """
        msg_hash_str = bin2hstr(tuple(msg_hash))
        ignore_peers = []
        if msg_hash_str in self.master_mr.requested_hash:
            ignore_peers = self.master_mr.requested_hash[msg_hash_str].peers_connection_list

        if not data:
            data = {'hash': sha256(msg_hash),
                    'type': msg_type}

        for peer in self.peer_connections:
            if peer in ignore_peers:
                continue
            peer.transport.write(self.protocol.wrap_message('MR', json_encode(data)))
Exemple #14
0
    def RFM(self, data):
        """
        Request Full Message
        This function request for the full message against,
        the Message Receipt received.
        :return:
        """

        # FIXME: Again, breaking encasulation
        # FIXME: Huge amount of lookups in dictionaries

        msg_hash = data['hash']
        msg_hash_str = bin2hstr(msg_hash)

        if msg_hash_str in self.master_mr.hash_msg:
            if msg_hash_str in self.master_mr.requested_hash:
                del self.master_mr.requested_hash[msg_hash_str]
            return

        peers_list = self.master_mr.requested_hash[
            msg_hash_str].peers_connection_list
        message_request = self.master_mr.requested_hash[msg_hash_str]
        for peer in peers_list:
            if peer in message_request.already_requested_peers:
                continue
            message_request.already_requested_peers.append(peer)

            peer.transport.write(
                peer.wrap_message('SFM', helper.json_encode(data)))
            call_later_obj = reactor.callLater(
                config.dev.message_receipt_timeout, self.RFM, data)
            message_request.callLater = call_later_obj
            return

        # If execution reach to this line, then it means no peer was able to provide
        # Full message for this hash thus the hash has to be deleted.
        # Moreover, negative points could be added to the peers, for this behavior
        if msg_hash_str in self.master_mr.requested_hash:
            del self.master_mr.requested_hash[msg_hash_str]
Exemple #15
0
    def RFM(self, data):  # Request full message, Move to factory
        msg_hash = data['hash']
        if msg_hash in self.factory.master_mr.hash_msg:
            if msg_hash in self.factory.master_mr.hash_callLater:
                del self.factory.master_mr.hash_callLater[msg_hash]
            return
        for peer in self.factory.master_mr.hash_peer[msg_hash]:
            if peer not in self.factory.master_mr.requested_hash[msg_hash]:
                self.factory.master_mr.requested_hash[msg_hash].append(peer)
                peer.transport.write(
                    self.wrap_message('SFM', helper.json_encode(data)))
                call_later_obj = reactor.callLater(
                    config.dev.message_receipt_timeout, self.RFM, data)
                self.factory.master_mr.hash_callLater[
                    msg_hash] = call_later_obj
                return

        # If executing reach to this line, then it means no peer was able to provide
        # Full message for this hash thus the hash has to be deleted.
        # Moreover, negative points could be added to the peers, for this behavior
        if msg_hash in self.factory.master_mr.hash_callLater:
            del self.factory.master_mr.hash_callLater[msg_hash]
Exemple #16
0
 def send_last_stake_reveal_one(self):
     for peer in self.peer_connections:
         peer.transport.write(
             self.protocol.wrap_message('R1',
                                        json_encode(self.last_reveal_one)))
Exemple #17
0
    def send_stake_reveal_one(self, blocknumber=None):
        if blocknumber is None:
            blocknumber = self.chain.block_chain_buffer.height(
            ) + 1  # next block..

        reveal_msg = {
            'stake_address':
            self.chain.mining_address,
            'block_number':
            blocknumber,
            # demonstrate the hash from last block to prevent building upon invalid block..
            'headerhash':
            self.chain.block_chain_buffer.get_strongest_headerhash(
                blocknumber - 1)
        }

        epoch = blocknumber // config.dev.blocks_per_epoch

        hash_chain = self.chain.block_chain_buffer.hash_chain_get(blocknumber)
        # +1 to skip first reveal
        reveal_msg['reveal_one'] = hash_chain[-1][:-1][::-1][
            blocknumber - (epoch * config.dev.blocks_per_epoch) + 1]
        reveal_msg['vote_hash'] = None
        reveal_msg['weighted_hash'] = None
        epoch_seed = self.chain.block_chain_buffer.get_epoch_seed(blocknumber)
        reveal_msg['seed'] = epoch_seed
        reveal_msg['SV_hash'] = self.chain.get_stake_validators_hash()

        stake_validators_list = self.chain.block_chain_buffer.get_stake_validators_list(
            blocknumber)
        target_chain = stake_validators_list.select_target(
            reveal_msg['headerhash'])

        hashes = hash_chain[target_chain]
        reveal_msg['vote_hash'] = hashes[:-1][::-1][
            blocknumber - (epoch * config.dev.blocks_per_epoch)]

        if reveal_msg['reveal_one'] is None or reveal_msg['vote_hash'] is None:
            logger.info(
                'reveal_one or vote_hash None for stake_address: %s selected hash: %s',
                reveal_msg['stake_address'], hash_chain[target_chain])
            logger.info('reveal_one %s', reveal_msg['reveal_one'])
            logger.info('vote_hash %s', reveal_msg['vote_hash'])
            logger.info('hash %s', hash_chain[target_chain])
            return

        reveal_msg['weighted_hash'] = self.chain.score(
            stake_address=reveal_msg['stake_address'],
            reveal_one=reveal_msg['reveal_one'],
            balance=self.chain.block_chain_buffer.get_st_balance(
                reveal_msg['stake_address'], blocknumber),
            seed=epoch_seed)

        y = False
        tmp_stake_reveal_one = []
        for r in self.chain.stake_reveal_one:  # need to check the reveal list for existence already, if so..reuse..
            if r[0] == self.chain.mining_address:
                if r[1] == reveal_msg['headerhash']:
                    if r[2] == blocknumber:
                        if y:
                            continue  # if repetition then remove..
                        else:
                            reveal_msg['reveal_one'] = r[3]
                            y = True
            tmp_stake_reveal_one.append(r)

        self.chain.stake_reveal_one = tmp_stake_reveal_one
        logger.info(
            '<<<Transmitting POS reveal_one %s %s', blocknumber,
            self.chain.block_chain_buffer.get_st_balance(
                reveal_msg['stake_address'], blocknumber))

        self.last_reveal_one = reveal_msg
        self.register_and_broadcast('R1', reveal_msg['vote_hash'],
                                    json_encode(reveal_msg))

        if not y:
            self.chain.stake_reveal_one.append([
                reveal_msg['stake_address'], reveal_msg['headerhash'],
                reveal_msg['block_number'], reveal_msg['reveal_one'],
                reveal_msg['weighted_hash'], reveal_msg['vote_hash']
            ])

        return reveal_msg['reveal_one']
Exemple #18
0
    def render_POST(self, request):
        req = request.content.read()
        jsQ = json.loads(req)

        self.result = {
            'status': 'fail',
            'message': '',
            'recoveredAddress': '',
            'hexseed': '',
            'mnemonic': ''
        }

        # Recover address from mnemonic
        if jsQ["type"] == "mnemonic":
            # Fail if no words provided
            if not jsQ["words"]:
                self.result[
                    "message"] = "You must provide your mnemonic phrase!"
                return bytes(helper.json_encode(self.result), 'utf-8')

            # FIXME: Validation should not be here, it should be part of mnemonic
            mnemonicphrase = jsQ["words"]

            if not validate_mnemonic(mnemonicphrase):
                self.result[
                    "message"] = "Invalid mnemonic phrase! It must contain exactly 32 valid words"
                return bytes(helper.json_encode(self.result), 'utf-8')

            # Try to recover
            try:
                addr = self.chain.wallet.get_new_address(
                    seed=mnemonic2bin(mnemonicphrase, wordlist))
                self.chain.wallet.append_wallet(addr)

                # Find hex/mnemonic for recovered wallet
                self.result["recoveredAddress"] = addr[1].get_address()
                self.result["hexseed"] = addr[1].get_hexseed()
                self.result["mnemonic"] = addr[1].get_mnemonic()

            except:
                self.result[
                    "message"] = "There was a problem restoring your address. " \
                                 "If you believe this is in error, please raise it with the QRL team."

                return bytes(helper.json_encode(self.result), 'utf-8')

        # Recover address from hexseed
        elif jsQ["type"] == "hexseed":
            if not jsQ["hexseed"] or not hexseed_to_seed(jsQ["hexseed"]):
                self.result["message"] = "Invalid Hex Seed!"
                return bytes(helper.json_encode(self.result), 'utf-8')

            # Try to recover
            try:
                addr = self.chain.wallet.get_new_address(
                    seed=hexseed_to_seed(jsQ["hexseed"]))
                self.chain.wallet.append_wallet(addr)

                # Find hex/mnemonic for recovered wallet
                self.result["recoveredAddress"] = addr[1].get_address()
                self.result["hexseed"] = addr[1].get_hexseed()
                self.result["mnemonic"] = addr[1].get_mnemonic()

            except:
                self.result[
                    "message"] = "There was a problem restoring your address. If you believe this is in error, please raise it with the QRL team."
                return bytes(helper.json_encode(self.result), 'utf-8')

        # Invalid selection
        else:
            self.result[
                "message"] = "You must select either mnemonic or hexseed recovery options to restore an address!"
            return bytes(helper.json_encode(self.result), 'utf-8')

        # If we got this far, it must have worked!
        self.result["status"] = "success"

        return bytes(helper.json_encode(self.result), 'utf-8')
Exemple #19
0
 def render_GET(self, request):
     return bytes(
         helper.json_encode(
             self.chain.wallet.list_addresses(self.chain.state,
                                              self.chain.transaction_pool)),
         'utf-8')
Exemple #20
0
    def send_tx(self, wallet_from, wallet_to, send_amount):
        self.txnResult = {
            'status': 'fail',
            'message': '',
            'txnhash': '',
            'from': wallet_from,
            'to': wallet_to,
            'amount': send_amount
        }

        # Check if local wallet number is higher than the number of local wallets that are saved
        if int(wallet_from) > len(
                self.chain.wallet.list_addresses(
                    self.chain.state, self.chain.transaction_pool)) - 1:
            self.txnResult[
                "message"] = "Invalid sending address. Try a valid number from your wallet - type wallet for details."
            return bytes(helper.json_encode(self.txnResult), 'utf-8')

        # if wallet_to is not a local wallet, and wallet_to is not prepended by Q and
        if len(wallet_to) > 1 and wallet_to[0] != 'Q' and self.state.state_hrs(
                wallet_to) != False:
            pass
        elif wallet_to[0] == 'Q':
            pass
        else:
            try:
                int(wallet_to)
            except:
                self.txnResult[
                    "message"] = "Invalid receiving address - addresses must start with Q."
                return bytes(helper.json_encode(self.txnResult), 'utf-8')

            if int(wallet_to) > len(
                    self.chain.wallet.list_addresses(
                        self.chain.state, self.chain.transaction_pool)) - 1:
                self.txnResult[
                    "message"] = "Invalid receiving address - addresses must start with Q."
                return bytes(helper.json_encode(self.txnResult), 'utf-8')

            wallet_to = int(wallet_to)

        # Check to see if sending amount > amount owned (and reject if so)
        # This is hard to interpret. Break it up?
        balance = self.state.state_balance(
            self.chain.wallet.address_bundle[int(wallet_from)].address)
        try:
            float(send_amount)
        except:
            self.txnResult[
                "message"] = "Invalid amount type. Type a number (less than or equal to the balance of the sending address)"
            return bytes(helper.json_encode(self.txnResult), 'utf-8')

        amount = decimal.Decimal(decimal.Decimal(send_amount) *
                                 100000000).quantize(
                                     decimal.Decimal('1'),
                                     rounding=decimal.ROUND_HALF_UP)

        if balance < amount:
            self.txnResult[
                "message"] = "Invalid amount to send. Type a number less than or equal to the balance of the sending address"
            return bytes(helper.json_encode(self.txnResult), 'utf-8')

        # Stop user from sending less than their entire balance if they've only
        # got one signature remaining.
        sigsremaining = self.chain.wallet.get_num_signatures(
            self.chain.wallet.address_bundle[int(wallet_from)].address)
        if sigsremaining is 1:
            if amount < balance:
                self.txnResult[
                    "message"] = "Stop! You only have one signing signature remaining. You should send your entire balance or the remainder will be lost!"
                return bytes(helper.json_encode(self.txnResult), 'utf-8')

        tx = self.chain.create_my_tx(txfrom=int(wallet_from),
                                     txto=bytes(wallet_to, 'utf-8'),
                                     amount=amount)

        if tx is False:
            self.txnResult["message"] = "Failed to Create txn"
            return bytes(helper.json_encode(self.txnResult), 'utf-8')

        if tx.validate_tx():
            block_chain_buffer = self.chain.block_chain_buffer
            tx_state = block_chain_buffer.get_stxn_state(
                blocknumber=block_chain_buffer.height(), addr=tx.txfrom)
            if not tx.state_validate_tx(
                    tx_state=tx_state,
                    transaction_pool=self.chain.transaction_pool):
                self.txnResult["message"] = "OTS key reused"
                return bytes(helper.json_encode(self.txnResult), 'utf-8')
        else:
            self.txnResult["message"] = "TXN failed at validate_tx"
            return bytes(helper.json_encode(self.txnResult), 'utf-8')

        # send the transaction to peers (ie send it to the network - we are done)
        self.p2pFactory.send_tx_to_peers(tx)

        print(('>>> TXN Hash: ' + str(tx.txhash) + ', From: ' +
               str(tx.txfrom) + ' To: ' + str(tx.txto) + ' For: ' +
               str(tx.amount / 100000000.000000000) + '\r\n' +
               '>>>created and sent into p2p network'))

        self.txnResult["status"] = "success"
        self.txnResult["txnhash"] = str(tx.txhash)
        self.txnResult["from"] = str(tx.txfrom)
        self.txnResult["to"] = str(tx.txto)
        self.txnResult["amount"] = str(tx.amount / 100000000.000000000)

        return bytes(helper.json_encode(self.txnResult), 'utf-8')
Exemple #21
0
    def send_stake_reveal_one(self, blocknumber=None):

        z = {
            'stake_address': self.chain.mining_address,
            'block_number': blocknumber
        }

        if not z['block_number']:
            z['block_number'] = self.chain.block_chain_buffer.height(
            ) + 1  # next block..

        z['headerhash'] = self.chain.block_chain_buffer.get_strongest_headerhash(
            z['block_number'] - 1
        )  # demonstrate the hash from last block to prevent building upon invalid block..
        epoch = z['block_number'] // config.dev.blocks_per_epoch
        hash_chain = self.chain.block_chain_buffer.hash_chain_get(
            z['block_number'])
        # +1 to skip first reveal
        z['reveal_one'] = hash_chain[-1][:-1][::-1][
            z['block_number'] - (epoch * config.dev.blocks_per_epoch) + 1]
        z['vote_hash'] = None
        z['weighted_hash'] = None
        epoch_seed = self.chain.block_chain_buffer.get_epoch_seed(blocknumber)
        z['seed'] = epoch_seed
        z['SV_hash'] = self.chain.get_stake_validators_hash()

        _, mhash = self.chain.select_hashchain(
            last_block_headerhash=self.chain.block_chain_buffer.
            get_strongest_headerhash(z['block_number'] - 1),
            stake_address=self.chain.mining_address,
            blocknumber=z['block_number'])

        for hashes in hash_chain:
            if hashes[-1] == mhash:
                z['vote_hash'] = hashes[:-1][::-1][
                    z['block_number'] - (epoch * config.dev.blocks_per_epoch)]
                break

        if z['reveal_one'] is None or z['vote_hash'] is None:
            logger.info(('reveal_one or vote_hash None for stake_address: ',
                         z['stake_address'], ' selected hash:', mhash))
            logger.info('reveal_one %s', z['reveal_one'])
            logger.info('vote_hash %s', z['vote_hash'])
            logger.info('hash %s', mhash)
            return

        z['weighted_hash'] = self.chain.score(
            stake_address=z['stake_address'],
            reveal_one=z['reveal_one'],
            balance=self.chain.block_chain_buffer.get_st_balance(
                z['stake_address'], blocknumber),
            seed=epoch_seed)

        y = False
        tmp_stake_reveal_one = []
        for r in self.chain.stake_reveal_one:  # need to check the reveal list for existence already, if so..reuse..
            if r[0] == self.chain.mining_address:
                if r[1] == z['headerhash']:
                    if r[2] == z['block_number']:
                        if y:
                            continue  # if repetition then remove..
                        else:
                            z['reveal_one'] = r[3]
                            y = True
            tmp_stake_reveal_one.append(r)

        self.chain.stake_reveal_one = tmp_stake_reveal_one
        logger.info(
            '<<<Transmitting POS reveal_one %s %s', blocknumber,
            self.chain.block_chain_buffer.get_st_balance(
                z['stake_address'], blocknumber))

        self.last_reveal_one = z
        self.register_and_broadcast('R1', z['vote_hash'], json_encode(z))
        # for peer in self.peers:
        #    peer.transport.write(self.f_wrap_message('R1', helper.json_encode(z)))
        # score = self.chain.score(stake_address=self.chain.mining_address,
        #                         reveal_one=z['reveal_one'],
        #                         balance=self.chain.block_chain_buffer.get_st_balance(self.chain.mining_address, blocknumber),
        #                         seed=epoch_seed)
        if not y:
            self.chain.stake_reveal_one.append([
                z['stake_address'], z['headerhash'], z['block_number'],
                z['reveal_one'], z['weighted_hash'], z['vote_hash']
            ])  # don't forget to store our reveal in stake_reveal_one

        return z['reveal_one']  # , z['block_number']