Exemple #1
0
    def test_create_hashchain(self):
        seed = sha256(b'test_seed')

        HASHCHAIN_SIZE = 100
        hcb = hashchain(seed, 1, HASHCHAIN_SIZE)
        self.assertIsNotNone(hcb)
        self.assertEqual(HASHCHAIN_SIZE + 1, len(hcb.hashchain))

        # FIXME: Why seed comes as an array of tuples?
        self.assertEqual(
            '127f5db0388cd82bd4af80b88e8d68409e1f70fd322f96b3f2aca55b0ade116f',
            bin2hstr(hcb.seed[0]))

        self.assertEqual(
            '1d3b37dedc74980941b3b65640e8d2851658feac0d38196f372ada9c2ac0b077',
            bin2hstr(hcb.hc_terminator))
        self.assertEqual(
            '1d3b37dedc74980941b3b65640e8d2851658feac0d38196f372ada9c2ac0b077',
            bin2hstr(hcb.hashchain[-1]))
        self.assertEqual(
            '127f5db0388cd82bd4af80b88e8d68409e1f70fd322f96b3f2aca55b0ade116f',
            bin2hstr(hcb.hashchain[0]))
        self.assertNotEqual(
            '127f5db0388cd82bd4af80b88e8d68409e1f70fd322f96b3f2aca55b0ade116f',
            bin2hstr(hcb.hashchain[1]))
        self.assertEqual(
            'ff7f4850bc6499e08e104c6967ee66e665e57d7e0e429072e646d14e1b92600a',
            bin2hstr(hcb.hashchain[50]))
Exemple #2
0
    def commit(self, chain, block, address_txn, ignore_save_wallet=False):
        # FIXME: This indexing approach is very inefficient

        blocks_left = helper.get_blocks_left(block.blockheader.blocknumber)

        staker = block.blockheader.stake_selector
        self.stake_validators_list.sv_list[staker].nonce += 1

        for address in address_txn:
            self._save_address_state(address, address_txn[address])

        for dup_tx in block.duplicate_transactions:
            if dup_tx.coinbase1.txto in self.stake_validators_list.sv_list:
                self.stake_validators_list.sv_list[dup_tx.coinbase1.txto].is_banned = True

        if blocks_left == 1:
            logger.info('EPOCH change: resetting stake_list, activating next_stake_list, updating PRF with '
                        'seed+entropy updating wallet hashchains..')

            self.stake_validators_list.move_next_epoch()
            # TODO: To be fixed later
            #self.stake_list_put(self.stake_validators_list.to_json())

            xmss = chain.wallet.address_bundle[0].xmss
            tmphc = hashchain(xmss.get_seed_private(), epoch=block.blockheader.epoch + 1)

            chain.hash_chain = tmphc.hashchain
            if not ignore_save_wallet:
                chain.wallet.save_wallet()

        self.state_set_blockheight(chain.height() + 1)

        logger.debug('%s %s tx passed verification.', bin2hstr(block.blockheader.headerhash), len(block.transactions))
        return True
Exemple #3
0
    def __init__(self, chain):
        self.chain = chain
        self.state = self.chain.state
        self.blocks = dict()
        self.size = config.dev.reorg_limit
        self.pending_blocks = dict()
        self.epoch = max(0, self.chain.height()
                         ) // config.dev.blocks_per_epoch  # Main chain epoch
        self.epoch_seed = None
        self.hash_chain = dict()

        self.slave_xmss = dict()

        self.slave_xmsspool = None
        self.assign_slave_xmsspool(0)

        # TODO: For the moment, only the first address is used (discussed with cyyber)
        private_seed = self.chain.wallet.address_bundle[
            0].xmss.get_seed_private()
        self._wallet_private_seeds = {self.epoch: private_seed}
        self.hash_chain[self.epoch] = hashchain(private_seed).hashchain

        self.tx_buffer = dict(
        )  # maintain the list of tx transaction that has been confirmed in buffer

        if self.chain.height() > 0:
            self.epoch = self.chain.m_blockchain[
                -1].blockheader.blocknumber // config.dev.blocks_per_epoch
Exemple #4
0
    def pre_pos_1(self, data=None):  # triggered after genesis for block 1..
        logger.info('pre_pos_1')
        # are we a staker in the stake list?

        if self.chain.mining_address not in self.chain.m_blockchain[0].stake_list:
            logger.info('not in stake list..no further pre_pos_x calls')
            return

        logger.info('mining address: %s in the genesis.stake_list', self.chain.mining_address)
        xmss = self.chain.wallet.address_bundle[0].xmss
        tmphc = hashchain(xmss.get_seed_private(), epoch=0)
        self.chain.hash_chain = tmphc.hashchain
        self.chain.block_chain_buffer.hash_chain[0] = tmphc.hashchain

        tmpbalance = self.chain.state.state_balance(self.chain.mining_address)
        slave_xmss = self.chain.block_chain_buffer.get_slave_xmss(0)
        if not slave_xmss:
            logger.info('Waiting for SLAVE XMSS to be done')
            reactor.callLater(5, self.pre_pos_1)
            return

        st = StakeTransaction().create(blocknumber=0,
                                       xmss=self.chain.wallet.address_bundle[0].xmss,
                                       slave_public_key=slave_xmss.pk(),
                                       hashchain_terminator=tmphc.hc_terminator,
                                       first_hash=tmphc.hashchain[-1][-2],
                                       balance=tmpbalance)

        self.chain.add_tx_to_pool(st)
        # send the stake tx to generate hashchain terminators for the staker addresses..
        self.p2pFactory.send_st_to_peers(st)
        logger.info('await delayed call to build staker list from genesis')
        reactor.callLater(5, self.pre_pos_2, st)
Exemple #5
0
    def post_block_logic(self, blocknumber):
        """
            post block logic we initiate the next POS cycle
            send R1, send ST, reset POS flags and remove unnecessary
            messages in chain.stake_reveal_one and _two..
        :return:
        """

        if self.p2pFactory.stake:
            next_stake_list = self.chain.block_chain_buffer.next_stake_list_get(
                blocknumber)

            epoch = blocknumber // config.dev.blocks_per_epoch
            epoch_blocknum = blocknumber - epoch * config.dev.blocks_per_epoch

            if epoch_blocknum < config.dev.stake_before_x_blocks and self.chain.mining_address not in next_stake_list:
                diff = max(
                    1,
                    int((config.dev.stake_before_x_blocks *
                         (1 - config.dev.st_txn_safety_margin) -
                         epoch_blocknum)))
                if random.randint(1, diff) == 1:
                    self.make_st_tx(blocknumber, None)

            elif epoch_blocknum >= config.dev.stake_before_x_blocks - 1 and self.chain.mining_address in next_stake_list:
                if not next_stake_list[self.chain.mining_address].first_hash:
                    threshold_blocknum = self.chain.block_chain_buffer.get_threshold(
                        blocknumber, self.chain.mining_address)
                    max_threshold_blocknum = config.dev.blocks_per_epoch
                    if threshold_blocknum == config.dev.low_staker_first_hash_block:
                        max_threshold_blocknum = config.dev.high_staker_first_hash_block

                    if threshold_blocknum - 1 <= epoch_blocknum < max_threshold_blocknum - 1:
                        diff = max(
                            1,
                            int((max_threshold_blocknum *
                                 (1 - config.dev.st_txn_safety_margin) -
                                 epoch_blocknum)))
                        if random.randint(1, diff) == 1:
                            xmss = self.chain.wallet.address_bundle[0].xmss
                            tmphc = hashchain(xmss.get_seed_private(),
                                              epoch=epoch + 1)
                            self.make_st_tx(blocknumber,
                                            tmphc.hashchain[-1][-2])

            stake_list = self.chain.block_chain_buffer.stake_list_get(
                blocknumber)

            delay = config.dev.minimum_minting_delay
            if self.chain.mining_address in stake_list:
                if stake_list[self.chain.mining_address].is_banned:
                    logger.warning('You have been banned.')
                else:
                    self.create_next_block(blocknumber)
                    delay = None

            last_blocknum = self.chain.block_chain_buffer.height()
            self.restart_post_block_logic(last_blocknum + 1, delay)

        return
Exemple #6
0
    def update_hash_chain(self, blocknumber):
        epoch = int((blocknumber + 1) // config.dev.blocks_per_epoch)
        logger.info('Created new hash chain')

        prev_private_seed = self._wallet_private_seeds[epoch - 1]
        self._wallet_private_seeds[epoch] = prev_private_seed
        self.hash_chain[epoch] = hashchain(prev_private_seed, epoch=epoch).hashchain
Exemple #7
0
    def pre_pos_1(self, data=None):  # triggered after genesis for block 1..
        logger.info('pre_pos_1')
        # are we a staker in the stake list?
        genesis_block = self.buffered_chain.get_block(0)
        found = False
        for genesisBalance in genesis_block.genesis_balance:
            if genesisBalance.address.encode(
            ) == self.buffered_chain.staking_address:
                logger.info('Found in Genesis Address %s %s',
                            genesisBalance.address.encode(),
                            genesisBalance.balance)
                found = True
                break

        if not found:
            return

        logger.info('mining address: %s in the genesis.stake_list',
                    self.buffered_chain.staking_address)
        xmss = self.buffered_chain.wallet.address_bundle[0].xmss
        tmphc = hashchain(xmss.get_seed_private(), epoch=0)
        self.buffered_chain.hash_chain[0] = tmphc.hashchain

        slave_xmss = self.buffered_chain.get_slave_xmss(0)
        if not slave_xmss:
            logger.info('Waiting for SLAVE XMSS to be done')
            reactor.callLater(5, self.pre_pos_1)
            return

        signing_xmss = self.buffered_chain.wallet.address_bundle[0].xmss
        st = StakeTransaction.create(activation_blocknumber=1,
                                     xmss=signing_xmss,
                                     slavePK=slave_xmss.pk(),
                                     hashchain_terminator=tmphc.hc_terminator)
        st.sign(signing_xmss)

        self.buffered_chain.tx_pool.add_tx_to_pool(st)

        # send the stake tx to generate hashchain terminators for the staker addresses..
        self.p2p_factory.broadcast_st(st)

        vote = Vote.create(
            addr_from=self.buffered_chain.wallet.address_bundle[0].address,
            blocknumber=0,
            headerhash=genesis_block.headerhash,
            xmss=slave_xmss)

        vote.sign(slave_xmss)

        self.buffered_chain.add_vote(vote)

        # send the stake votes for genesis block
        self.p2p_factory.broadcast_vote(vote)

        logger.info('await delayed call to build staker list from genesis')
        reactor.callLater(5, self.pre_pos_2, st)
Exemple #8
0
    def pre_pos_2(self, data=None):
        logger.info('pre_pos_2')
        if self.chain.height() >= 1:
            return
        # assign hash terminators to addresses and generate a temporary stake list ordered by st.hash..

        tmp_list = []

        for tx in self.chain.transaction_pool:
            if tx.subtype == qrl.core.Transaction_subtypes.TX_SUBTYPE_STAKE:
                if tx.txfrom in self.chain.m_blockchain[0].stake_list and tx.first_hash:
                    tmp_list.append([tx.txfrom, tx.hash, 0, tx.first_hash, GenesisBlock().get_info()[tx.txfrom], tx.slave_public_key])
                    self.chain.state.stake_validators_list.add_sv(tx.txfrom,
                                                                  tx.slave_public_key,
                                                                  tx.hash,
                                                                  tx.first_hash,
                                                                  GenesisBlock().get_info()[tx.txfrom])

        self.chain.block_chain_buffer.epoch_seed = self.chain.state.calc_seed(tmp_list)

        self.chain.stake_list = sorted(tmp_list,
                                       key=lambda staker: self.chain.score(stake_address=staker[0],
                                                                           reveal_one=bin2hstr(sha256(reduce(lambda set1, set2: set1 + set2, staker[1]))),
                                                                           balance=staker[4],
                                                                           seed=self.chain.block_chain_buffer.epoch_seed))

        self.chain.block_chain_buffer.epoch_seed = format(self.chain.block_chain_buffer.epoch_seed, 'x')

        logger.info('genesis stakers ready = %s / %s', len(self.chain.stake_list), config.dev.minimum_required_stakers)
        logger.info('node address: %s', self.chain.mining_address)

        if len(self.chain.stake_list) < config.dev.minimum_required_stakers:  # stake pool still not full..reloop..
            self.p2pFactory.send_st_to_peers(data)
            logger.info('waiting for stakers.. retry in 5s')
            reactor.callID = reactor.callLater(5, self.pre_pos_2, data)
            return

        if self.chain.mining_address == self.chain.stake_list[0][0]:
            logger.info('designated to create block 1: building block..')

            tmphc = hashchain(self.chain.wallet.address_bundle[0].xmss.get_seed_private())

            # create the genesis block 2 here..
            reveal_hash, vote_hash = self.chain.select_hashchain(self.chain.m_blockchain[-1].blockheader.headerhash,
                                                           self.chain.mining_address,
                                                           tmphc.hashchain,
                                                           blocknumber=1)
            b = self.chain.m_create_block(reveal_hash[-2], vote_hash[-2])
            self.pre_block_logic(b)
        else:
            logger.info('await block creation by stake validator: %s', self.chain.stake_list[0][0])
            self.last_bk_time = time.time()
            self.restart_unsynced_logic()
        return
Exemple #9
0
    def test_hashchain_verify(self):
        seed = sha256(b'test_seed')

        HASHCHAIN_SIZE = 100
        hcb = hashchain(seed, 1, HASHCHAIN_SIZE)
        self.assertIsNotNone(hcb)
        self.assertEqual(HASHCHAIN_SIZE + 1, len(hcb.hashchain))

        for i, value in enumerate(hcb.hashchain):
            tmp = sha256_n(value, HASHCHAIN_SIZE - i)
            logger.info("{:-4} {} {}".format(i, bin2hstr(value), bin2hstr(tmp)))
            self.assertEqual(hcb.hc_terminator, tmp)
Exemple #10
0
    def test_hashchain_verify(self):
        seed = sha256(b'test_seed')

        HASHCHAIN_SIZE = 100
        hcb = hashchain(seed, 1, HASHCHAIN_SIZE)
        self.assertIsNotNone(hcb)
        self.assertEqual(HASHCHAIN_SIZE + 1, len(hcb.hashchain))

        for i, value in enumerate(hcb.hashchain):
            tmp = sha256_n(value, HASHCHAIN_SIZE - i)
            print("{:-4} {} {}".format(i, bin2hstr(value), bin2hstr(tmp)))
            self.assertEqual(hcb.hc_terminator, tmp)
Exemple #11
0
    def add_block_mainchain(self, chain, block, validate=True):
        # TODO : minimum block validation in unsynced _state
        blocknum = block.blockheader.blocknumber
        epoch = int(blocknum // config.dev.blocks_per_epoch)
        prev_headerhash = block.blockheader.prev_blockheaderhash

        # FIXME: Chain should be checking this. Avoid complex references
        if blocknum <= chain.height():
            return

        if blocknum - 1 == chain.height():
            if prev_headerhash != chain.m_blockchain[-1].blockheader.headerhash:
                logger.info('prev_headerhash of block doesnt match with headerhash of m_blockchain')
                return
        elif blocknum - 1 > 0:
            if blocknum - 1 not in self.blocks or prev_headerhash != self.blocks[blocknum - 1][0].block.blockheader.headerhash:
                logger.info('No block found in buffer that matches with the prev_headerhash of received block')
                return

        if validate:
            if not chain.m_add_block(block):
                logger.info("Failed to add block by m_add_block, re-requesting the block #%s", blocknum)
                return
        else:
            if self.state.state_add_block(chain, block, ignore_save_wallet=True) is True:
                chain.m_blockchain.append(block)

        block_left = config.dev.blocks_per_epoch - (
            block.blockheader.blocknumber - (block.blockheader.epoch * config.dev.blocks_per_epoch))

        self.add_txns_buffer()
        if block_left == 1:  # As state_add_block would have already moved the next stake list to stake_list
            self.epoch_seed = bin2hstr(hex(self.state.stake_validators_list.calc_seed()))

            private_seed = chain.wallet.address_bundle[0].xmss.get_seed_private()
            self._wallet_private_seeds[epoch + 1] = private_seed
            self.hash_chain[epoch + 1] = hashchain(private_seed, epoch=epoch + 1).hashchain

            if epoch in self._wallet_private_seeds:
                del self._wallet_private_seeds[epoch]
            if epoch in self.slave_xmss:
                del self.slave_xmss[epoch]
        else:
            self.epoch_seed = bin2hstr(sha256(block.blockheader.reveal_hash + hstr2bin(self.epoch_seed)))

        chain.update_last_tx(block)
        chain.update_tx_metadata(block)
        self.epoch = epoch
        return True
Exemple #12
0
    def test_create_hashchain(self):
        seed = sha256(b'test_seed')

        HASHCHAIN_SIZE = 100
        hcb = hashchain(seed, 1, HASHCHAIN_SIZE)
        self.assertIsNotNone(hcb)
        self.assertEqual(HASHCHAIN_SIZE + 1, len(hcb.hashchain))

        # FIXME: Why seed comes as an array of tuples?
        self.assertEqual('127f5db0388cd82bd4af80b88e8d68409e1f70fd322f96b3f2aca55b0ade116f',
                         bin2hstr(hcb.seed[0]))

        self.assertEqual('1d3b37dedc74980941b3b65640e8d2851658feac0d38196f372ada9c2ac0b077',
                         bin2hstr(hcb.hc_terminator))
        self.assertEqual('1d3b37dedc74980941b3b65640e8d2851658feac0d38196f372ada9c2ac0b077',
                         bin2hstr(hcb.hashchain[-1]))
        self.assertEqual('127f5db0388cd82bd4af80b88e8d68409e1f70fd322f96b3f2aca55b0ade116f',
                         bin2hstr(hcb.hashchain[0]))
        self.assertNotEqual('127f5db0388cd82bd4af80b88e8d68409e1f70fd322f96b3f2aca55b0ade116f',
                            bin2hstr(hcb.hashchain[1]))
        self.assertEqual('ff7f4850bc6499e08e104c6967ee66e665e57d7e0e429072e646d14e1b92600a',
                         bin2hstr(hcb.hashchain[50]))
Exemple #13
0
    def state_update_genesis(self, chain, block, address_txn):
        # Start Updating coin base txn
        tx = block.transactions[0]  # Expecting only 1 txn of COINBASE subtype in genesis block
        pubhash = tx.generate_pubhash(tx.PK, tx.ots_key)

        if tx.nonce != 1:
            logger.warning('nonce incorrect, invalid tx')
            logger.warning('subtype: %s', tx.subtype)
            logger.warning('%s actual: %s expected: %s', tx.txfrom, tx.nonce, address_txn[tx.txfrom][0] + 1)
            return False
        # TODO: To be fixed later
        if pubhash in address_txn[tx.txfrom][2]:
            logger.warning('pubkey reuse detected: invalid tx %s', tx.txhash)
            logger.warning('subtype: %s', tx.subtype)
            return False

        address_txn[tx.txto][1] += tx.amount
        address_txn[tx.txfrom][2].append(pubhash)

        # Coinbase update end here
        tmp_list = []
        for tx in block.transactions:
            if tx.subtype == TX_SUBTYPE_STAKE:
                # update txfrom, hash and stake_nonce against genesis for current or next stake_list
                tmp_list.append([tx.txfrom,
                                 tx.hash,
                                 0,
                                 tx.first_hash,
                                 GenesisBlock().get_info()[tx.txfrom],
                                 tx.slave_public_key])

                if tx.txfrom == block.blockheader.stake_selector:
                    if tx.txfrom in chain.m_blockchain[0].stake_list:
                        self.stake_validators_list.add_sv(tx.txfrom,
                                                          tx.slave_public_key,
                                                          tx.hash,
                                                          tx.first_hash,
                                                          tx.balance)
                        self.stake_validators_list.sv_list[tx.txfrom].nonce += 1
                    else:
                        logger.warning('designated staker not in genesis..')
                        return False
                else:
                    if tx.txfrom in chain.m_blockchain[0].stake_list:
                        self.stake_validators_list.add_sv(tx.txfrom,
                                                          tx.slave_public_key,
                                                          tx.hash,
                                                          tx.first_hash,
                                                          tx.balance)
                    else:
                        self.stake_validators_list.add_next_sv(tx.txfrom,
                                                               tx.slave_public_key,
                                                               tx.hash,
                                                               tx.first_hash,
                                                               tx.balance)

                pubhash = tx.generate_pubhash(tx.PK, tx.ots_key)
                address_txn[tx.txfrom][2].append(pubhash)

        epoch_seed = self.stake_validators_list.calc_seed()
        chain.block_chain_buffer.epoch_seed = epoch_seed
        self.put_epoch_seed(epoch_seed)

        chain.block_chain_buffer.epoch_seed = chain.state.calc_seed(tmp_list)
        chain.stake_list = sorted(tmp_list,
                                  key=lambda staker: chain.score(stake_address=staker[0],
                                                                 reveal_one=bin2hstr(sha256(reduce(
                                                                     lambda set1, set2: set1 + set2, staker[1]))),
                                                                 balance=staker[4],
                                                                 seed=chain.block_chain_buffer.epoch_seed))
        chain.block_chain_buffer.epoch_seed = format(chain.block_chain_buffer.epoch_seed, 'x')
        if chain.stake_list[0][0] != block.blockheader.stake_selector:
            logger.info('stake selector wrong..')
            return

        xmss = chain.wallet.address_bundle[0].xmss
        tmphc = hashchain(xmss.get_seed_private(), epoch=0)

        chain.hash_chain = tmphc.hashchain
        chain.wallet.save_wallet()
        return True
Exemple #14
0
    def pre_pos_2(self, data=None):
        logger.info('pre_pos_2')
        if self.buffered_chain.height >= 1:
            return
        # assign hash terminators to addresses and generate a temporary stake list ordered by st.hash..

        tmp_list = []
        seed_list = []
        genesis_block = self.buffered_chain.get_block(0)
        total_genesis_stake_amount = 0
        for tx in self.buffered_chain.tx_pool.transaction_pool:
            tx.pbdata.nonce = 1
            if tx.subtype == qrl_pb2.Transaction.STAKE:
                for genesisBalance in genesis_block.genesis_balance:
                    if tx.txfrom == genesisBalance.address.encode(
                    ) and tx.activation_blocknumber == 1:
                        tmp_list.append([
                            tx.txfrom, tx.hash, 0, genesisBalance.balance,
                            tx.slave_public_key
                        ])
                        seed_list.append(tx.hash)
                        # FIXME: This goes to stake validator list without verification, Security Risk
                        self.buffered_chain._chain.pstate.stake_validators_tracker.add_sv(
                            genesisBalance.balance, tx, 1)
                        total_genesis_stake_amount += genesisBalance.balance

        self.buffered_chain.epoch_seed = calc_seed(seed_list)

        #  TODO : Needed to be reviewed later
        self.buffered_chain.stake_list = sorted(
            tmp_list,
            key=lambda staker: score(
                stake_address=staker[0],
                reveal_one=bin2hstr(
                    sha256(
                        str(
                            reduce(lambda set1, set2: set1 + set2,
                                   tuple(staker[1]))).encode())),
                balance=staker[3],
                seed=self.buffered_chain.epoch_seed))

        # self.buffered_chain.epoch_seed = format(self.buffered_chain.epoch_seed, 'x')  # FIXME: Why hex string?

        logger.info('genesis stakers ready = %s / %s',
                    len(self.buffered_chain.stake_list),
                    config.dev.minimum_required_stakers)
        logger.info('node address: %s', self.buffered_chain.staking_address)

        # stake pool still not full..reloop..
        if len(self.buffered_chain.stake_list
               ) < config.dev.minimum_required_stakers:
            self.p2p_factory.broadcast_st(data)
            logger.info('waiting for stakers.. retry in 5s')
            reactor.callID = reactor.callLater(5, self.pre_pos_2, data)
            return

        voteMetadata = self.buffered_chain.get_consensus(0)
        consensus_ratio = voteMetadata.total_stake_amount / total_genesis_stake_amount

        if consensus_ratio < 0.51:
            logger.info('Consensus lower than 51%%.. retry in 5s')
            reactor.callID = reactor.callLater(5, self.pre_pos_2, data)
            return

        if self.buffered_chain.staking_address == self.buffered_chain.stake_list[
                0][0]:
            logger.info('designated to create block 1: building block..')

            tmphc = hashchain(self.buffered_chain.wallet.address_bundle[0].
                              xmss.get_seed_private())

            # create the genesis block 2 here..
            reveal_hash = self.buffered_chain.select_hashchain(
                self.buffered_chain.staking_address,
                tmphc.hashchain,
                blocknumber=1)

            b = self.buffered_chain.create_block(
                reveal_hash[-2])  # FIXME: This is incorrect, rewire
            self.pre_block_logic(b)  # FIXME: Ignore return value?
        else:
            logger.info('await block creation by stake validator: %s',
                        self.buffered_chain.stake_list[0][0])
            self.last_bk_time = time.time()
            self.restart_unsynced_logic()