def submit_send_tx(self, tx : SimpleTransaction) -> bool: # TODO: Review this if tx and tx.validate_tx(): block_chain_buffer = self.chain.block_chain_buffer block_number = block_chain_buffer.height() + 1 tx_state = block_chain_buffer.get_stxn_state(block_number, tx.txfrom) if tx.state_validate_tx(tx_state=tx_state, transaction_pool=self.chain.transaction_pool): self.chain.add_tx_to_pool(tx) self.chain.wallet.save_wallet() self.p2pfactory.send_tx_to_peers(tx) return True return False
def create_send_tx(self, addr_from, addr_to, amount, fee, xmss_pk, xmss_ots_key): return SimpleTransaction.create(addr_from=addr_from, addr_to=addr_to, amount=amount, fee=fee, xmss_pk=xmss_pk, xmss_ots_key=xmss_ots_key)
def recv_tx(self, json_tx_obj): try: tx = SimpleTransaction().json_to_transaction(json_tx_obj) except Exception as e: logger.info( 'tx rejected - unable to decode serialised data - closing connection' ) logger.exception(e) self.transport.loseConnection() return if not self.factory.master_mr.isRequested(tx.get_message_hash(), self): return if tx.txhash in self.factory.chain.prev_txpool or tx.txhash in self.factory.chain.pending_tx_pool_hash: return del self.factory.chain.prev_txpool[0] self.factory.chain.prev_txpool.append(tx.txhash) for t in self.factory.chain.transaction_pool: # duplicate tx already received, would mess up nonce.. if tx.txhash == t.txhash: return self.factory.chain.update_pending_tx_pool(tx, self) self.factory.master_mr.register(tx.get_message_hash(), json_tx_obj, 'TX') self.factory.broadcast(tx.get_message_hash(), 'TX') if not self.factory.txn_processor_running: txn_processor = TxnProcessor( block_chain_buffer=self.factory.chain.block_chain_buffer, pending_tx_pool=self.factory.chain.pending_tx_pool, transaction_pool=self.factory.chain.transaction_pool, txhash_timestamp=self.factory.chain.txhash_timestamp) task_defer = TxnProcessor.create_cooperate( txn_processor).whenDone() task_defer.addCallback(self.factory.reset_processor_flag) \ .addErrback(self.factory.reset_processor_flag_with_err) self.factory.txn_processor_running = True return
def create_my_tx(self, txfrom, txto, amount, fee=0): if isinstance(txto, int): txto = self.wallet.address_bundle[txto].address xmss = self.wallet.address_bundle[txfrom].xmss tx_state = self.block_chain_buffer.get_stxn_state( self.block_chain_buffer.height() + 1, xmss.get_address()) tx = SimpleTransaction().create(tx_state=tx_state, txto=txto, amount=amount, xmss=xmss, fee=fee) if tx and tx.state_validate_tx(tx_state=tx_state, transaction_pool=self.transaction_pool): self.add_tx_to_pool(tx) self.wallet.save_wallet() # need to keep state after tx ..use self.wallet.info to store index.. # far faster than loading the 55mb self.wallet.. return tx return False
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._format_qrlamount(tx.amount), 'type': tx.subtype } addr['transactions'].append(tmp_txn) addr['status'] = 'ok' return json_print_telnet(addr)
def _search_address(self, address): addr = {'transactions': []} txnhash_added = set() # FIXME: breaking encapsulation and accessing DB/cache directly from API if not self.factory.state.state_address_used(address): addr['status'] = 'error' addr['error'] = 'Address not found' addr['parameter'] = address return json_print_telnet(addr) # FIXME: This is a duplicate of balance # FIXME: breaking encapsulation and accessing DB/cache directly from API nonce, balance, pubhash_list = self.factory.state.state_get_address( address) addr['state'] = {} addr['state']['address'] = address addr['state']['balance'] = self._format_qrlamount(balance) addr['state']['nonce'] = nonce for s in self.factory.state.stake_list_get(): if address == s[0]: addr['stake'] = {} addr['stake']['selector'] = s[2] # pubhashes used could be put here.. tmp_transactions = [] for tx in self.factory.chain.transaction_pool: if tx.subtype not in (TX_SUBTYPE_TX, TX_SUBTYPE_COINBASE): continue if tx.txto == address or tx.txfrom == address: logger.info('%s found in transaction pool', address) tmp_txn = { 'subtype': tx.subtype, 'txhash': bin2hstr(tx.txhash), 'block': 'unconfirmed', 'amount': self._format_qrlamount(tx.amount), 'nonce': tx.nonce, 'ots_key': tx.ots_key, 'txto': tx.txto, 'txfrom': tx.txfrom, 'timestamp': 'unconfirmed' } if tx.subtype == TX_SUBTYPE_TX: tmp_txn['fee'] = self._format_qrlamount(tx.fee) tmp_txn.subtype = Transaction.tx_id_to_name(tx.subtype) tmp_transactions.append(tmp_txn) txnhash_added.add(tx.txhash) addr['transactions'] = tmp_transactions my_txn = [] try: my_txn = self.factory.state.db.get('txn_' + address) except: pass for txn_hash in my_txn: txn_metadata = self.factory.state.db.get(txn_hash) dict_txn_metadata = json.loads(txn_metadata[0]) if dict_txn_metadata['subtype'] == TX_SUBTYPE_TX: tx = SimpleTransaction().json_to_transaction(txn_metadata[0]) elif dict_txn_metadata['subtype'] == TX_SUBTYPE_COINBASE: tx = CoinBase().json_to_transaction(txn_metadata[0]) if (tx.txto == address or tx.txfrom == address) and tx.txhash not in txnhash_added: logger.info('%s found in block %s', address, str(txn_metadata[1])) tmp_txn = { 'subtype': tx.subtype, 'txhash': bin2hstr(tx.txhash), 'block': txn_metadata[1], 'timestamp': txn_metadata[2], 'amount': self._format_qrlamount(tx.amount), 'nonce': tx.nonce, 'ots_key': tx.ots_key, 'txto': tx.txto, 'txfrom': tx.txfrom } if tx.subtype == TX_SUBTYPE_TX: tmp_txn['fee'] = self._format_qrlamount(tx.fee) tmp_txn['subtype'] = Transaction.tx_id_to_name( tmp_txn['subtype']) addr['transactions'].append(tmp_txn) txnhash_added.add(tx.txhash) if len(addr['transactions']) > 0: addr['state']['transactions'] = len(addr['transactions']) if addr == {'transactions': {}}: addr = { 'status': 'error', 'error': 'address not found', 'method': 'address', 'parameter': address } else: addr['status'] = 'ok' return json_print_telnet(addr)