def make_st_tx(self, blocknumber, first_hash): balance = self.chain.block_chain_buffer.get_stxn_state(blocknumber, self.chain.mining_address)[1] if balance < config.dev.minimum_staking_balance_required: logger.warning('Staking not allowed due to insufficient balance') logger.warning('Balance %s', balance) return slave_xmss = self.chain.block_chain_buffer.get_next_slave_xmss(blocknumber) if not slave_xmss: return st = StakeTransaction().create( blocknumber=blocknumber, xmss=self.chain.wallet.address_bundle[0].xmss, slave_public_key=slave_xmss.pk(), first_hash=first_hash, balance=balance ) self.p2pFactory.send_st_to_peers(st) for num in range(len(self.chain.transaction_pool)): t = self.chain.transaction_pool[num] if t.subtype == qrl.core.Transaction_subtypes.TX_SUBTYPE_STAKE and st.hash == t.hash: if st.get_message_hash() == t.get_message_hash(): return self.chain.remove_tx_from_pool(t) break self.chain.add_tx_to_pool(st) self.chain.wallet.save_wallet()
def ST(self, data): """ Stake Transaction This function processes whenever a Transaction having subtype ST is received. :return: """ try: st = StakeTransaction().json_to_transaction(data) except Exception as e: logger.error( 'st rejected - unable to decode serialised data - closing connection' ) logger.exception(e) self.transport.loseConnection() return if not self.factory.master_mr.isRequested(st.get_message_hash(), self): return if len( self.factory.chain.m_blockchain ) == 1 and st.epoch > 0: # catch error for new nodes listening for ST's from later epochs return for t in self.factory.chain.transaction_pool: if st.get_message_hash() == t.get_message_hash(): return tx_state = self.factory.chain.block_chain_buffer.get_stxn_state( blocknumber=self.factory.chain.block_chain_buffer.height() + 1, addr=st.txfrom) if st.validate_tx() and st.state_validate_tx(tx_state=tx_state): self.factory.chain.add_tx_to_pool(st) else: hashes = [] for item in st.hash: hashes.append(bin2hstr(item)) logger.warning('>>>ST %s invalid state validation failed..', hashes) return self.factory.register_and_broadcast('ST', st.get_message_hash(), st.transaction_to_json()) return
def broadcast_st(self, st: StakeTransaction): logger.info('<<<Transmitting ST: %s', st.activation_blocknumber) self.register_and_broadcast('ST', st.get_message_hash(), st.to_json())