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!")
except: return 0.0 def transactionList(tx_id=None): try: params = {"value": config["deposit-address"]["privateKey"]} if tx_id is not None: params["id"] = str(tx_id) return send_request("/local/account/transfers/incoming", "POST", json.dumps(params))["data"] except: return [] dbd = database.Deposits(coinname) last_tx_id = dbd.getLastCheckedBlockHeight() tx_list = transactionList() if len(tx_list) > 0: while last_tx_id is None or tx_list[-1]["meta"]["id"] > last_tx_id: portion = transactionList(tx_list[-1]["meta"]["id"]) if len(portion) == 0: break tx_list += portion if last_tx_id is not None: while len(tx_list) > 0 and tx_list[-1]["meta"]["id"] <= last_tx_id: del tx_list[-1] topBlockHeight = blockCount()
def processIncomingDeposits(): global walletrpc dbd = database.Deposits(coinname) lastCheckedBlock = dbd.getLastCheckedBlockHeight() fromBlock = 0 if lastCheckedBlock is None else lastCheckedBlock + 1 toBlock = int(walletrpc.eth_blockNumber(), 16) new_txlist = {} if fromBlock <= toBlock: res = walletrpc.eth_getLogs({ "fromBlock": hex(fromBlock), "toBlock": hex(toBlock), "address": config["contract-address"], "topics": [ "0x028be863b16e1ebb120a887a86a8c08b41d33e317f4307ef113b1ff7e7a03873" ] }) for logEntry in res: txid = logEntry["transactionHash"] userid = int(logEntry["data"][-72:-64], 16) amount = str(int(logEntry["data"][-64:], 16)).rjust(19, '0') amount = amount[:-18] + "." + amount[-18:] blockNumber = int(logEntry["blockNumber"], 16) new_txlist[(txid, 0)] = (userid, amount, blockNumber) 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 = toBlock - 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 = toBlock - 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(toBlock, new_unacceptedList)
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 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)