From 536a577d0cb52d1ee01eabd0df5ba1d5d2ef1ea5 Mon Sep 17 00:00:00 2001 From: Tobi Okedeji Date: Fri, 19 Jul 2024 20:22:32 +0100 Subject: [PATCH] update faucet to queue instead --- checker.js | 22 + config/config.js | 2 +- faucet.js | 49 ++- package.json | 4 +- views/index.ejs | 7 +- yarn.lock | 1041 ++++++++++++++++++++++++++++++++++++---------- 6 files changed, 901 insertions(+), 224 deletions(-) diff --git a/checker.js b/checker.js index 651a98e..4dd172d 100644 --- a/checker.js +++ b/checker.js @@ -45,4 +45,26 @@ export class FrequencyChecker { } }); } + + async updateRequestStatus(requestId, status, message, data=null) { + const db = this.db + let request + try { + request = await db.get(requestId) + request.statuses.push(status) + } catch (error) { + if (error.status == 404) { + request = {statuses: [status]} + } else { + console.log(error, 'error') + } + } + await db.put(requestId, {data, statuses: request.statuses, messsage: message ? message : ''}); + } + + async getRequestStatus(requestId) { + const db = this.db + const request = await db.get(requestId); + return request + } } diff --git a/config/config.js b/config/config.js index 8bc379a..393dd59 100644 --- a/config/config.js +++ b/config/config.js @@ -35,7 +35,7 @@ export default { }, tx: { amount: [ - { denom: "uallo", amount: "20000000000000000000" }, + { denom: "uallo", amount: "1000000000" }, ], fee: { amount: [{ denom: "uallo", amount: "500" }], diff --git a/faucet.js b/faucet.js index 71ec0e3..1c91374 100644 --- a/faucet.js +++ b/faucet.js @@ -9,9 +9,14 @@ import { bech32 } from 'bech32'; import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing"; import { SigningStargateClient } from "@cosmjs/stargate"; +import { Mutex } from 'async-mutex'; +import { v4 } from 'uuid'; + import conf from './config/config.js' import { FrequencyChecker } from './checker.js'; +const mutex = new Mutex(); + // load config console.log("loaded config: ", conf) @@ -83,8 +88,24 @@ app.get('/balance/:chain', async (req, res) => { res.send(balance); }) +app.get('/status/:requestId', async (req, res, next) => { + return Promise.resolve().then(async () => { + const { requestId } = req.params; + + const status = await checker.getRequestStatus(requestId); + if (status.statuses.length > 0) { + res.json(status); + } else { + res.status(404).json({ error: 'Request ID not found' }); + } + }).catch(next) +}); + app.get('/send/:chain/:address', async (req, res, next) => { return Promise.resolve().then(async () => { + const requestId = v4(); + await checker.updateRequestStatus(requestId, 'pending', 'Request received'); + const {chain, address} = req.params; const ip = req.headers['x-real-ip'] || req.headers['X-Real-IP'] || req.headers['X-Forwarded-For'] || req.ip console.log('request tokens to ', address, ip) @@ -93,20 +114,35 @@ app.get('/send/:chain/:address', async (req, res, next) => { const chainConf = conf.blockchains.find(x => x.name === chain) if (chainConf && (address.startsWith(chainConf.sender.option.prefix) || address.startsWith('0x'))) { if( await checker.checkAddress(address, chain) && await checker.checkIp(`${chain}${ip}`, chain) ) { + + res.send({ requestId, message: "Faucet processing request", recipient: address}) checker.update(`${chain}${ip}`) // get ::1 on localhost - const ret = await sendTx(address, chain); - await checker.update(address) - res.send({ result: ret, tokens: chainConf.tx.amount, recipient: address}) + + const release = await mutex.acquire(); + let sendRes; + try { + const sendRes = await sendTx(address, chain); + await checker.updateRequestStatus(requestId, 'success', 'request processed successfully', sendRes); + await checker.update(address) + } catch (err) { + console.log(err, 'error'); + await checker.updateRequestStatus(requestId, 'failed', 'Failed, Please contact to admin.'); + } finally { + release(); + } }else { + await checker.updateRequestStatus(requestId, 'failed', `Too Many Requests`); res.send({ result: { - code: 429, + requestId, message: 'Too Many Requests', + recipient: address } }) } } else { - res.send({ result: `Address [${address}] is not supported.` }) + await checker.updateRequestStatus(requestId, 'failed', `Address [${address}] is not supported.`); + res.send({requestId, message: `Address [${address}] is not supported.`, recipient: address }) } // } catch (err) { // console.error(err); @@ -115,7 +151,8 @@ app.get('/send/:chain/:address', async (req, res, next) => { } else { // send result - res.send({ result: 'address is required' }); + await checker.updateRequestStatus(requestId, 'failed', `address not provided`); + res.send({requestId, message: 'address is required' }); }}).catch(next) }) diff --git a/package.json b/package.json index d606fed..436e825 100644 --- a/package.json +++ b/package.json @@ -32,12 +32,14 @@ "@ethersproject/wallet": "^5.7.0", "@hanchon/evmos-ts-wallet": "^0.2.0", "@tharsis/transactions": "^0.2.6", + "async-mutex": "^0.5.0", "bech32": "^2.0.0", "ejs": "^3.1.9", "ethers": "^5.7.1", "evmosjs": "0.3.3", "express": "^4.18.2", "level": "^8.0.0", - "nodemodule": "^0.3.0" + "nodemodule": "^0.3.0", + "uuid": "^10.0.0" } } diff --git a/views/index.ejs b/views/index.ejs index 522b625..81d502d 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -107,13 +107,12 @@ document.getElementById("button-loading").style.display = 'none'; // show result this.message = ` -