Merge pull request #1042 from cosmos/faucet-prevent-draining

Faucet can only be used once a day per address
This commit is contained in:
Simon Warta 2022-02-16 15:40:52 +01:00 committed by GitHub
commit 54a3587e0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 1 deletions

View File

@ -84,7 +84,10 @@ and this project adheres to
@cosmjs/launchpad. They are re-exported in @cosmjs/launchpad for backwards
compatibility.
- @cosmjs/stargate: Add `GasPrice.toString`.
- @cosmjs/faucet: Added a new functionality to faucet: Each address is only
allowed to get credits once every 24h to prevent draining. ([#962]))
[#962]: https://github.com/cosmos/cosmjs/issues/962
[#938]: https://github.com/cosmos/cosmjs/issues/938
[#932]: https://github.com/cosmos/cosmjs/issues/932
[#878]: https://github.com/cosmos/cosmjs/issues/878

View File

@ -16,6 +16,7 @@ export interface ChainConstants {
export class Webserver {
private readonly api = new Koa();
private readonly addressCounter = new Map<string, Date>();
public constructor(faucet: Faucet, chainConstants: ChainConstants) {
this.api.use(cors());
@ -58,13 +59,22 @@ export class Webserver {
// context.request.body is set by the bodyParser() plugin
const requestBody = context.request.body;
const creditBody = RequestParser.parseCreditBody(requestBody);
const { address, denom } = creditBody;
if (!isValidAddress(address, constants.addressPrefix)) {
throw new HttpError(400, "Address is not in the expected format for this chain.");
}
const entry = this.addressCounter.get(address);
if (entry !== undefined) {
if (entry.getTime() + 24 * 3600 > Date.now()) {
throw new HttpError(
405,
"Too many request from the same address. Blocked to prevent draining. Please wait 24h and try it again!",
);
}
}
const availableTokens = await faucet.availableTokens();
const matchingDenom = availableTokens.find((availableDenom) => availableDenom === denom);
if (matchingDenom === undefined) {
@ -73,6 +83,8 @@ export class Webserver {
try {
await faucet.credit(address, matchingDenom);
// Count addresses to prevent draining
this.addressCounter.set(address, new Date());
} catch (e) {
console.error(e);
throw new HttpError(500, "Sending tokens failed");