def dashboard_data(): # get remote block height remote_node = "https://testnode1.wavesnodes.com" if not cfg.testnet: remote_node = "https://nodes.wavesnodes.com" response = get(remote_node + "/blocks/height") remote_block_height = response.json()["height"] # get locally scanned block height scanned_block_height = 0 last_block = Block.last_block(db.session) if last_block: scanned_block_height = last_block.num # get incomming tx count incomming_tx_count = Transaction.count(db.session) # get created tx count created_tx_count = CreatedTransaction.count(db.session) # get balance of local wallet path = f"assets/balance/{cfg.address}/{cfg.asset_id}" response = requests.get(cfg.node_http_base_url + path) zap_balance = response.json()["balance"] # get the balance of the main wallet path = f"transactions/info/{cfg.asset_id}" response = requests.get(cfg.node_http_base_url + path) try: issuer = response.json()["sender"] path = f"addresses/balance/{issuer}" response = requests.get(cfg.node_http_base_url + path) master_waves_balance = response.json()["balance"] except: issuer = "n/a" master_waves_balance = "n/a" # return data return {"remote_block_height": remote_block_height, "scanned_block_height": scanned_block_height, \ "incomming_tx_count": incomming_tx_count, "created_tx_count": created_tx_count, \ "zap_balance": zap_balance, "zap_address": cfg.address, \ "master_waves_balance": master_waves_balance, "master_waves_address": issuer, \ "asset_id": cfg.asset_id, \ "testnet": cfg.testnet, "remote_node": remote_node}
def block_check(self): # set current scanned block last_block = Block.last_block(db_session) if last_block: current_scanned_block = last_block.num else: current_scanned_block = cfg.startblock # check if no accounts created so we can skip to the most recent block with self.account_lock: acct_count = Account.count(db_session) if acct_count == 0: current_scanned_block = get_current_block_number() - 1 # check for reorgs and invalidate any blocks (and associated txs) block_num = current_scanned_block block = Block.from_number(db_session, current_scanned_block) if block: any_reorgs = False block_hash = get_block_hash(block_num) if not block_hash: self.logger.error("unable to get hash for block %d" % block_num) return while block_hash != block.hash: self.logger.info( "block %d hash does not match current blockchain, must have been reorged" % block_num) block.set_reorged(db_session) any_reorgs = True # decrement block_num, set new current_scanned_block block_num -= 1 current_scanned_block = block_num # now do the previous block block = Block.from_number(db_session, block_num) if not block: break block_hash = get_block_hash(block_num) if any_reorgs: db_session.commit() # get address list from db with self.account_lock: addresses = Account.all_active_addresses(db_session) # scan for new blocks current_block = get_current_block_number() while current_scanned_block < current_block and self.keep_running: block_num = current_scanned_block + 1 start = time.time() block_hash, txs, tx_count = get_block_hash_and_txs( block_num, addresses) # check for reorged blocks now reorged *back* into the main chain block = Block.from_hash(db_session, block_hash) if block: self.logger.info("block %s (was #%d) now un-reorged" % (block_hash.hex(), block.num)) block.num = block_num block.reorged = False else: block = Block(block_num, block_hash) db_session.add(block) db_session.flush() for key in txs.keys(): self.logger.info("adding txs for " + key) for tx in txs[key]: self.logger.info(" - %s, %s" % (tx["hash"].hex(), tx["value"])) Account.add_txs(db_session, key, block.id, txs[key]) db_session.commit() current_scanned_block = block_num self.logger.info( "#block# %d scan took %f seconds (%d addresses, %d txs)" % (block_num, time.time() - start, len(addresses), tx_count)) # scan for pending transactions start = time.time() txs, tx_count = scan_pending_txs(addresses) for key in txs.keys(): self.logger.info("adding txs for " + key) for tx in txs[key]: self.logger.info(" - %s, %s" % (tx["hash"].hex(), tx["value"])) Account.add_txs(db_session, key, None, txs[key]) db_session.commit() self.logger.info( "!pending! tx scan took %f seconds (%d addresses, %d txs)" % (time.time() - start, len(addresses), tx_count))
def root(): last_block = Block.last_block(db_session) num_accounts = Account.count(db_session) return "last block: %d, %s<br/>number of accounts tracked: %d" % ( last_block.num, last_block.hash.hex(), num_accounts)
def blockloop(): logger.info("ZapWeb blockloop started") # get last block from the db last_block = Block.last_block(db.session) if last_block: scanned_block_num = last_block.num else: scanned_block_num = cfg.start_block while 1: gevent.sleep(5) # check for reorgs and invalidate any blocks (and associated txs) block = Block.from_number(db.session, scanned_block_num) if block: any_reorgs = False blk_hash = block_hash(scanned_block_num) if not blk_hash: msg = f"unable to get hash (from node) for block {scanned_block_num}" logger.error(msg) utils.email_death(logger, msg) sys.exit(1) while blk_hash != block.hash: logger.info("block %d hash does not match current blockchain, must have been reorged" % scanned_block_num) block.set_reorged(db.session) any_reorgs = True # decrement scanned_block_num scanned_block_num -= 1 # now do the previous block block = Block.from_number(db.session, scanned_block_num) if not block: msg = f"unable to get hash (from db) for block {scanned_block_num}" logger.error(msg) utils.email_death(logger, msg) sys.exit(1) blk_hash = block_hash(scanned_block_num) if any_reorgs: db.session.commit() # scan for new blocks # use "block_height() - 1" because with the WavesNG protocol the block can have new transactions # added until the next block is found while block_height() - 1 > scanned_block_num: block = block_at(scanned_block_num + 1) res, reason = block_chk(block) if not res: logger.error(f"failed to get block at {scanned_block_num + 1} ({reason})") break blk_hash = block_hash(block) # check for reorged blocks now reorged *back* into the main chain dbblk = Block.from_hash(db.session, blk_hash) if dbblk: logger.info("block %s (was #%d) now un-reorged" % (blk_hash, dbblk.num)) dbblk.num = scanned_block_num + 1 dbblk.reorged = False else: dbblk = Block(block["timestamp"], block["height"], blk_hash) db.session.add(dbblk) db.session.flush() # add transactions to db if "transactions" in block: for tx in block["transactions"]: if tx["type"] == 4: recipient = tx["recipient"] asset_id = tx["assetId"] if recipient == cfg.address and asset_id == cfg.asset_id: txid = tx["id"] logger.info(f"new tx {txid}") attachment = tx["attachment"] if attachment: attachment = base58.b58decode(attachment) logger.info(f" {attachment}") invoice_id = utils.extract_invoice_id(logger, attachment) if invoice_id: logger.info(f" {invoice_id}") dbtx = Transaction(txid, tx["sender"], recipient, tx["amount"], attachment, invoice_id, dbblk.id) db.session.add(dbtx) scanned_block_num = block["height"] logger.debug(f"scanned block {scanned_block_num}") if scanned_block_num % 100 == 0: db.session.commit() gevent.sleep(0) db.session.commit()
def last_blocknum(): last_block = Block.last_block(db_session) if last_block: return jsonify({"last_blocknum": last_block.num}) return jsonify({"last_blocknum": 0})