def processDepositAddressRequests(): global walletrpc dbda = database.DepositAddresses(coinname) for userid in dbda.listPendingRequests(100): address = walletrpc.getnewaddress(str(userid)) dbda.storeAddress(userid, address) print("Generated {0} deposit address {1} for user {2}".format( coinname.upper(), address, userid)) for userid, address in dbda.listUnnotifiedRequests(100): print("Notify {0} deposit address {1} for user {2}".format( coinname.upper(), address, userid)) if notify.notify(reason="address", coin=coinname, userid=userid, address=address): dbda.markAsNotified(userid) print("> Accepted!") else: print("> Rejected!")
def processDepositAddressRequests(n=100): global walletrpc dbda = database.DepositAddresses(coinname) dbd = database.Deposits(coinname) topBlock = int(walletrpc.eth_blockNumber(), 16) for userid in dbda.listPendingRequests(n): address = walletrpc.personal_newAccount(config["password"]) dbda.storeAddress(userid, address) dbd.setLastCheckedBlockHeight2(userid, topBlock) for userid, address in dbda.listUnnotifiedRequests(100): logger.message("Notify {0} deposit address {1} for user {2}".format( coinname.upper(), address, userid)) if notify.notify(reason="address", coin=coinname, userid=userid, address=address): dbda.markAsNotified(userid) logger.message("> Accepted!") else: logger.message("> Rejected!")
#! /usr/bin/env python2 import sys, json import config, database coin = sys.argv[1] userid = int(sys.argv[2]) address = database.DepositAddresses(coin).getAddress(userid) res = {} res["coin"] = coin res["userid"] = userid res["pending"] = (address is None) res["address"] = address print json.dumps({"result": res})
def processIncomingDeposits(): global walletrpc dbda = database.DepositAddresses(coinname) dbd = database.Deposits(coinname) allAddressesSorted = [] for userid, address in dbda.listAllDepositAddresses(): lastCheckedBlock = dbd.getLastCheckedBlockHeight(userid) if lastCheckedBlock is None: lastCheckedBlock = 0 allAddressesSorted.append((lastCheckedBlock, userid, address)) allAddressesSorted.sort() for lastCheckedBlock, userid, address in allAddressesSorted: requiredConfirmations = 10 topBlockHeight = int(walletrpc.eth_blockNumber(), 16) checkUpToBlock = topBlockHeight - requiredConfirmations logger.message( "Checking deposits for user {0}, block range {1}-{2}".format( userid, lastCheckedBlock, checkUpToBlock)) if lastCheckedBlock >= checkUpToBlock: continue processDepositAddressRequests(1) old_txlist = dbd.listUnacceptedDeposits(userid) new_unacceptedList = {} forwardtx = dbd.getForwardTransaction(userid) forwardtxBlock = None if forwardtx is not None: receipt = walletrpc.eth_getTransactionReceipt(forwardtx) if receipt is not None: forwardtxBlock = int(receipt["blockNumber"], 16) gasUsed = int(receipt["gasUsed"], 16) forwardtxInfo = walletrpc.eth_getTransactionByHash(forwardtx) gasPrice = int(forwardtxInfo["gasPrice"], 16) value = int(forwardtxInfo["value"], 16) forwardtxDebit = value + gasPrice * gasUsed if forwardtxBlock is None or forwardtxBlock > checkUpToBlock: for (txhash, blockHeight, amount) in findDepositsInBlockRange(address, lastCheckedBlock, checkUpToBlock): if not depositNotify(txhash, 0, userid, amount, topBlockHeight - blockHeight + 1): new_unacceptedList[txhash] = (amount, blockHeight) newLastCheckedBlock = checkUpToBlock shouldResetForwardTxHash = False else: for (txhash, blockHeight, amount) in findDepositsInBlockRange(address, lastCheckedBlock, forwardtxBlock - 1): if not depositNotify(txhash, 0, userid, amount, topBlockHeight - blockHeight + 1): new_unacceptedList[txhash] = (amount, blockHeight) balanceBefore = int( walletrpc.eth_getBalance(address, hex(forwardtxBlock - 1)), 16) balanceAfter = int( walletrpc.eth_getBalance(address, hex(forwardtxBlock)), 16) # print balanceAfter, balanceBefore, forwardtxDebit # sys.exit(1) for (txhash, blockHeight, amount) in findDepositsInBlock( address, forwardtxBlock, balanceAfter - balanceBefore + forwardtxDebit): if not depositNotify(txhash, 0, userid, amount, topBlockHeight - blockHeight + 1): new_unacceptedList[txhash] = (amount, blockHeight) newLastCheckedBlock = forwardtxBlock shouldResetForwardTxHash = True for (txhash, (amount, blockHeight)) in old_txlist.items(): if not depositNotify(txhash, 0, userid, amount, topBlockHeight - blockHeight + 1): new_unacceptedList[txhash] = (amount, blockHeight) if new_unacceptedList == old_txlist: new_unacceptedList = None dbd.setLastCheckedBlockHeight2( userid=userid, lastCheckedBlock=newLastCheckedBlock, unacceptedTransactions=new_unacceptedList, resetForwardTx=shouldResetForwardTxHash) if forwardtx is None and "transfer" in config: balance = int(walletrpc.eth_getBalance(address, "latest"), 16) if balance >= 1E18 * config["transfer"]["min-amount"]: logger.message("Forwarding money to {0}...".format( config["transfer"]["address"])) gasPrice = int(walletrpc.eth_gasPrice(), 16) gas = config["transfer"]["gas-amount"] walletrpc.personal_unlockAccount(address, config["password"]) # print {"from": address, "to": config["transfer"]["address"], "gasPrice": hex(gasPrice), "gas": hex(gas), "value": hex(balance-gas*gasPrice)} txhash = walletrpc.eth_sendTransaction({ "from": address, "to": config["transfer"]["address"], "gasPrice": hex(gasPrice), "gas": hex(gas), "value": hex(balance - gas * gasPrice) }) dbd.setForwardTransaction(userid, txhash) logger.message("> OK ({0})".format(txhash))
def processDepositAddressRequests(): global walletrpc, accountIsLocked dbda = database.DepositAddresses(coinname) depositMasterAddress = config["deposit-master"] contractAddress = config["contract-address"] if "deposit-master-balance" in config["alert"]: minimumBalance = config["alert"]["deposit-master-balance"] if minimumBalance is not None: currentBalance = int( walletrpc.eth_getBalance(depositMasterAddress, "latest"), 16) / 1E18 if currentBalance < minimumBalance: notify.notify(reason="alarm", message="Low deposit master account balance", data={ "coin": coinname.upper(), "address": depositMasterAddress, "minimum-balance": minimumBalance, "current-balance": currentBalance }) pendingTransactions = [] for userid in dbda.listPendingRequests(100): useridAsHex = hex(userid)[2:].rjust(64, '0') address = walletrpc.eth_call( { "from": depositMasterAddress, "to": contractAddress, "data": "0x877806af" + useridAsHex }, "latest") if address != "0x" + 64 * "0": address = "0x" + address[-40:] dbda.storeAddress(userid, address) else: if accountIsLocked: walletrpc.personal_unlockAccount(depositMasterAddress, config["password"]) accountIsLocked = False txhash = walletrpc.eth_sendTransaction({ "from": depositMasterAddress, "to": contractAddress, "data": "0x32331feb" + useridAsHex, "gas": "0x493e0" }) pendingTransactions.append(txhash) for txhash in pendingTransactions: while 1: receipt = walletrpc.eth_getTransactionReceipt(txhash) if receipt is not None: break time.sleep(1) for logentry in receipt["logs"]: if len(logentry["topics"]) == 1 and logentry["topics"][ 0] == "0xd3c75d3774b298f1efe8351f0635db8123b649572a5b810e96f5b97e11f43031": userid = int(logentry["data"][-72:-64], 16) address = "0x" + logentry["data"][-40:] dbda.storeAddress(userid, address) break for userid, address in dbda.listUnnotifiedRequests(100): print("Notify {0} deposit address {1} for user {2}".format( coinname.upper(), address, userid)) if notify.notify(reason="address", coin=coinname, userid=userid, address=address): dbda.markAsNotified(userid) print("> Accepted!") else: print("> Rejected!")
def processIncomingDeposits(): global walletrpc dbd = database.Deposits(coinname) dbda = database.DepositAddresses(coinname) lastCheckedBlock = dbd.getLastCheckedBlockHeight() if lastCheckedBlock is None: res = walletrpc.listsinceblock("", 1) else: res = walletrpc.listsinceblock( walletrpc.getblockhash(lastCheckedBlock), 1) topBlockHash = res["lastblock"] topBlockHeight = walletrpc.getblock(topBlockHash, True)["height"] new_txlist = {} for tx in res["transactions"]: # It's not an incoming transaction if tx["category"] != "receive": continue # Extract account id - either directly from the transaction or indirectly # (use our database to find userid by receiving address) if trustWalletAccounts: try: account = int(tx["account"]) except: continue else: account = dbda.getUseridByAddress(tx["address"]) if account is None: continue # block height of transaction conf = tx["confirmations"] if conf == 0: new_txlist[(tx["txid"], tx["vout"])] = (account, str(tx["amount"]), None) else: new_txlist[(tx["txid"], tx["vout"])] = (account, str(tx["amount"]), topBlockHeight - conf + 1) old_txlist = dbd.listUnacceptedDeposits() new_unacceptedList = {} for (txid, vout), tx in new_txlist.items(): userid, amount, blockHeight = tx conf = 0 if blockHeight is not None: conf = topBlockHeight - blockHeight + 1 if (txid, vout) not in old_txlist: if not depositNotify(txid, vout, userid, amount, conf): new_unacceptedList[(txid, vout)] = tx else: if not depositNotify(txid, vout, userid, amount, conf): new_unacceptedList[(txid, vout)] = tx del old_txlist[(txid, vout)] for (txid, vout), tx in old_txlist.items(): userid, amount, blockHeight = tx conf = 0 if blockHeight is not None: conf = topBlockHeight - blockHeight + 1 # TODO: check transaction because it may have ceased to exist if not depositNotify(txid, vout, userid, amount, conf): new_unacceptedList[(txid, vout)] = tx dbd.setLastCheckedBlockHeight(topBlockHeight, new_unacceptedList)