def output(quantity, asset): try: if asset not in ("fraction", "leverage"): return str(util.value_out(db, quantity, asset)) + " " + asset else: return str(util.value_out(db, quantity, asset)) except exceptions.AssetError: return "<AssetError>" except decimal.DivisionByZero: return "<DivisionByZero>" except TypeError: return "<None>"
def asset_conservation(db): logger.debug('Checking for conservation of assets.') supplies = util.supplies(db) held = util.held(db) for asset in supplies.keys(): asset_issued = supplies[asset] asset_held = held[asset] if asset in held and held[asset] != None else 0 if asset_issued != asset_held: raise SanityError('{} {} issued ≠ {} {} held'.format(util.value_out(db, asset_issued, asset), asset, util.value_out(db, asset_held, asset), asset)) logger.debug('{} has been conserved ({} {} both issued and held)'.format(asset, util.value_out(db, asset_issued, asset), asset))
def log(db, command, category, bindings): cursor = db.cursor() for element in bindings.keys(): try: str(bindings[element]) except KeyError: bindings[element] = "<Error>" # Slow?! def output(quantity, asset): try: if asset not in ("fraction", "leverage"): return str(util.value_out(db, quantity, asset)) + " " + asset else: return str(util.value_out(db, quantity, asset)) except exceptions.AssetError: return "<AssetError>" except decimal.DivisionByZero: return "<DivisionByZero>" except TypeError: return "<None>" if command == "update": if category == "order": logger.debug("Database: set status of order {} to {}.".format(bindings["tx_hash"], bindings["status"])) elif category == "bet": logger.debug("Database: set status of bet {} to {}.".format(bindings["tx_hash"], bindings["status"])) elif category == "order_matches": logger.debug( "Database: set status of order_match {} to {}.".format(bindings["order_match_id"], bindings["status"]) ) elif category == "bet_matches": logger.debug( "Database: set status of bet_match {} to {}.".format(bindings["bet_match_id"], bindings["status"]) ) # TODO: elif category == 'balances': # logger.debug('Database: set balance of {} in {} to {}.'.format(bindings['address'], bindings['asset'], output(bindings['quantity'], bindings['asset']).split(' ')[0])) elif command == "insert": if category == "credits": logger.debug( "Credit: {} to {} #{}# <{}>".format( output(bindings["quantity"], bindings["asset"]), bindings["address"], bindings["action"], bindings["event"], ) ) elif category == "debits": logger.debug( "Debit: {} from {} #{}# <{}>".format( output(bindings["quantity"], bindings["asset"]), bindings["address"], bindings["action"], bindings["event"], ) ) elif category == "sends": logger.info( "Send: {} from {} to {} ({}) [{}]".format( output(bindings["quantity"], bindings["asset"]), bindings["source"], bindings["destination"], bindings["tx_hash"], bindings["status"], ) ) elif category == "orders": logger.info( "Order: {} ordered {} for {} in {} blocks, with a provided fee of {} {} and a required fee of {} {} ({}) [{}]".format( bindings["source"], output(bindings["give_quantity"], bindings["give_asset"]), output(bindings["get_quantity"], bindings["get_asset"]), bindings["expiration"], bindings["fee_provided"] / config.UNIT, config.SCH, bindings["fee_required"] / config.UNIT, config.SCH, bindings["tx_hash"], bindings["status"], ) ) elif category == "order_matches": logger.info( "Order Match: {} for {} ({}) [{}]".format( output(bindings["forward_quantity"], bindings["forward_asset"]), output(bindings["backward_quantity"], bindings["backward_asset"]), bindings["id"], bindings["status"], ) ) elif category == "shellpays": logger.info( "{} Payment: {} paid {} to {} for order match {} ({}) [{}]".format( config.SCH, bindings["source"], output(bindings["shell_amount"], config.SCH), bindings["destination"], bindings["order_match_id"], bindings["tx_hash"], bindings["status"], ) ) elif category == "issuances": if bindings["transfer"]: logger.info( "Issuance: {} transfered asset {} to {} ({}) [{}]".format( bindings["source"], bindings["asset"], bindings["issuer"], bindings["tx_hash"], bindings["status"], ) ) elif bindings["locked"]: logger.info( "Issuance: {} locked asset {} ({}) [{}]".format( bindings["issuer"], bindings["asset"], bindings["tx_hash"], bindings["status"] ) ) else: if bindings["divisible"]: divisibility = "divisible" unit = config.UNIT else: divisibility = "indivisible" unit = 1 try: quantity = util.value_out(db, bindings["quantity"], None, divisible=bindings["divisible"]) except Exception as e: quantity = "?" logger.info( "Issuance: {} created {} of {} asset {} ({}) [{}]".format( bindings["issuer"], quantity, divisibility, bindings["asset"], bindings["tx_hash"], bindings["status"], ) ) elif category == "broadcasts": if bindings["locked"]: logger.info( "Broadcast: {} locked his feed ({}) [{}]".format( bindings["source"], bindings["tx_hash"], bindings["status"] ) ) else: logger.info( "Broadcast: " + bindings["source"] + " at " + isodt(bindings["timestamp"]) + " with a fee of {}%".format(output(D(bindings["fee_fraction_int"] / 1e8) * D(100), "fraction")) + " (" + bindings["tx_hash"] + ")" + " [{}]".format(bindings["status"]) ) elif category == "bets": logger.info( "Bet: {} against {}, by {}, on {}".format( output(bindings["wager_quantity"], config.SHP), output(bindings["counterwager_quantity"], config.SHP), bindings["source"], bindings["feed_address"], ) ) elif category == "bet_matches": placeholder = "" if bindings["target_value"] >= 0: # Only non‐negative values are valid. placeholder = " that " + str(output(bindings["target_value"], "value")) if bindings["leverage"]: placeholder += ", leveraged {}x".format(output(bindings["leverage"] / 5040, "leverage")) logger.info( "Bet Match: {} for {} against {} for {} on {} at {}{} ({}) [{}]".format( util.BET_TYPE_NAME[bindings["tx0_bet_type"]], output(bindings["forward_quantity"], config.SHP), util.BET_TYPE_NAME[bindings["tx1_bet_type"]], output(bindings["backward_quantity"], config.SHP), bindings["feed_address"], isodt(bindings["deadline"]), placeholder, bindings["id"], bindings["status"], ) ) elif category == "dividends": logger.info( "Dividend: {} paid {} per unit of {} ({}) [{}]".format( bindings["source"], output(bindings["quantity_per_unit"], bindings["dividend_asset"]), bindings["asset"], bindings["tx_hash"], bindings["status"], ) ) elif category == "burns": logger.info( "Burn: {} burned {} for {} ({}) [{}]".format( bindings["source"], output(bindings["burned"], config.SCH), output(bindings["earned"], config.SHP), bindings["tx_hash"], bindings["status"], ) ) elif category == "cancels": logger.info("Cancel: {} ({}) [{}]".format(bindings["offer_hash"], bindings["tx_hash"], bindings["status"])) elif category == "rps": log_message = "RPS: {} opens game with {} possible moves and a wager of {}".format( bindings["source"], bindings["possible_moves"], output(bindings["wager"], "SHP") ) logger.info(log_message) elif category == "rps_matches": log_message = "RPS Match: {} is playing a {}-moves game with {} with a wager of {} ({}) [{}]".format( bindings["tx0_address"], bindings["possible_moves"], bindings["tx1_address"], output(bindings["wager"], "SHP"), bindings["id"], bindings["status"], ) logger.info(log_message) elif category == "rpsresolves": if bindings["status"] == "valid": rps_matches = list( cursor.execute("""SELECT * FROM rps_matches WHERE id = ?""", (bindings["rps_match_id"],)) ) assert len(rps_matches) == 1 rps_match = rps_matches[0] log_message = "RPS Resolved: {} is playing {} on a {}-moves game with {} with a wager of {} ({}) [{}]".format( rps_match["tx0_address"], bindings["move"], rps_match["possible_moves"], rps_match["tx1_address"], output(rps_match["wager"], "SHP"), rps_match["id"], rps_match["status"], ) else: log_message = "RPS Resolved: {} [{}]".format(bindings["tx_hash"], bindings["status"]) logger.info(log_message) elif category == "order_expirations": logger.info("Expired order: {}".format(bindings["order_hash"])) elif category == "order_match_expirations": logger.info("Expired Order Match awaiting payment: {}".format(bindings["order_match_id"])) elif category == "bet_expirations": logger.info("Expired bet: {}".format(bindings["bet_hash"])) elif category == "bet_match_expirations": logger.info("Expired Bet Match: {}".format(bindings["bet_match_id"])) elif category == "bet_match_resolutions": # DUPE cfd_type_id = util.BET_TYPE_ID["BullCFD"] + util.BET_TYPE_ID["BearCFD"] equal_type_id = util.BET_TYPE_ID["Equal"] + util.BET_TYPE_ID["NotEqual"] if bindings["bet_match_type_id"] == cfd_type_id: if bindings["settled"]: logger.info( "Bet Match Settled: {} credited to the bull, {} credited to the bear, and {} credited to the feed address ({})".format( output(bindings["bull_credit"], config.SHP), output(bindings["bear_credit"], config.SHP), output(bindings["fee"], config.SHP), bindings["bet_match_id"], ) ) else: logger.info( "Bet Match Force‐Liquidated: {} credited to the bull, {} credited to the bear, and {} credited to the feed address ({})".format( output(bindings["bull_credit"], config.SHP), output(bindings["bear_credit"], config.SHP), output(bindings["fee"], config.SHP), bindings["bet_match_id"], ) ) elif bindings["bet_match_type_id"] == equal_type_id: logger.info( "Bet Match Settled: {} won the pot of {}; {} credited to the feed address ({})".format( bindings["winner"], output(bindings["escrow_less_fee"], config.SHP), output(bindings["fee"], config.SHP), bindings["bet_match_id"], ) ) elif category == "rps_expirations": logger.info("Expired RPS: {}".format(bindings["rps_hash"])) elif category == "rps_match_expirations": logger.info("Expired RPS Match: {}".format(bindings["rps_match_id"])) elif category == "contracts": logger.info("New Contract: {}".format(bindings["contract_id"])) elif category == "executions": """ try: payload_hex = binascii.hexlify(bindings['payload']).decode('ascii') except TypeError: payload_hex = '<None>' try: output_hex = binascii.hexlify(bindings['output']).decode('ascii') except TypeError: output_hex = '<None>' logger.info('Execution: {} executed contract {}, funded with {}, at a price of {} (?), at a final cost of {}, reclaiming {}, and also sending {}, with a data payload of {}, yielding {} ({}) [{}]'.format(bindings['source'], bindings['contract_id'], output(bindings['gas_start'], config.SHP), bindings['gas_price'], output(bindings['gas_cost'], config.SHP), output(bindings['gas_remaining'], config.SHP), output(bindings['value'], config.SHP), payload_hex, output_hex, bindings['tx_hash'], bindings['status'])) """ if bindings["contract_id"]: logger.info( "Execution: {} executed contract {} ({}) [{}]".format( bindings["source"], bindings["contract_id"], bindings["tx_hash"], bindings["status"] ) ) else: logger.info( "Execution: {} created contract {} ({}) [{}]".format( bindings["source"], bindings["output"], bindings["tx_hash"], bindings["status"] ) ) elif category == "destructions": logger.info( "Destruction: {} destroyed {} {} with tag ‘{}’({}) [{}]".format( bindings["source"], bindings["quantity"], bindings["asset"], bindings["tag"], bindings["tx_hash"], bindings["status"], ) ) cursor.close()