Skip to content

Commit

Permalink
Using PAPI for both tests and code
Browse files Browse the repository at this point in the history
  • Loading branch information
mutantcornholio committed May 10, 2024
1 parent a239854 commit a266142
Show file tree
Hide file tree
Showing 44 changed files with 1,920 additions and 1,239 deletions.
18 changes: 6 additions & 12 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
# Exclude all:
*

# Include what is actually used:
!package.json
!yarn.lock
!tsconfig.json
!env.*.config.json
!src

/src/**/*.e2e.ts
/src/**/*.spec.ts
.github
.env
/node_modules
/build
/client
/data
6 changes: 3 additions & 3 deletions .github/workflows/E2E.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
- name: Setup Node.js for use with actions
uses: actions/[email protected]
with:
node-version: "18.16"
node-version: 20
- run: yarn install --frozen-lockfile
- name: Download Polkadot and parachain binaries
run: |
Expand All @@ -36,8 +36,8 @@ jobs:
source wait_until.sh 'curl -s "127.0.0.1:9933"'
source wait_until.sh 'curl -s "127.0.0.1:9934"'
working-directory: e2e
- name: Build e2e types
run: yarn generate:papi:e2e
- name: Generate PAPI types
run: yarn generate:papi
- name: Build faucet
run: yarn build:docker
- name: Run the E2E tests
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
${{ runner.os }}-yarn-
- name: Install deps in root
run: yarn install --frozen-lockfile
- run: yarn generate:papi:e2e
- run: yarn generate:papi
- name: Install deps in client
run: yarn install --frozen-lockfile
working-directory: client
Expand Down
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ storage.db
sqlite.db
build
e2e/containter_logs
e2e/zombienet_logs
e2e/zombienet

# Autogenerated
env.*.config.json.d.ts
!.env.example

/data
/src/test/codegen
/src/codegen
8 changes: 4 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
FROM docker.io/library/node:18.16.0-alpine
FROM docker.io/library/node:20.11.1-alpine

# uncomment to fix build on MacOS Apple Silicon chip
# RUN apk add --no-cache python3 make g++
RUN apk add git
RUN apk add --no-cache python3 make g++
# RUN apk add git

ARG VCS_REF=master
ARG BUILD_DATE=""
Expand All @@ -20,7 +20,7 @@ LABEL io.parity.image.authors="[email protected]" \

WORKDIR /faucet

COPY ./package.json ./yarn.lock ./
COPY ./package.json ./yarn.lock ./polkadot-api.json ./
RUN yarn --frozen-lockfile

COPY . .
Expand Down
2 changes: 1 addition & 1 deletion client/.env
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ PUBLIC_CAPTCHA_KEY=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI

PUBLIC_FAUCET_URL=
# uncomment to direct requests to local instance
# PUBLIC_FAUCET_URL=http://localhost:5555/drip/web/
PUBLIC_FAUCET_URL=http://localhost:5555/drip/web/

PUBLIC_ISSUE_LINK=https://github.com/paritytech/polkadot-testnet-faucet/issues/new/choose
PUBLIC_FORUM="https://forum.polkadot.network/t/experiencing-trouble-accessing-our-rococo-faucet-please-post-here/2952"
9 changes: 2 additions & 7 deletions e2e/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ command -v polkadot-parachain || echo "No polkadot-parachain in PATH"
Next, in the root of this repository, start the Zombienet:

```bash
npx --yes @zombienet/[email protected] --provider native --dir e2e/zombienet_logs spawn e2e/zombienet.native.toml
yarn e2e:zombienet
```

Verify that it's working correctly by opening the [relaychain](https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:9933#/explorer) and [parachain](https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:9934#/explorer) explorers,
Expand All @@ -103,12 +103,7 @@ curl localhost:9934
yarn build:docker
```

4. Generate PAPI types for e2e tests

```bash
yarn generate:papi:e2e
```

# TODO: UPDATE DOCS
These types are generated based on `.scale` files in `e2e/` directory. To regenerate these files using live zombienet nodes, use `papi update --config e2e/polkadot-api-e2e.json` command.

5. Run the tests
Expand Down
12 changes: 0 additions & 12 deletions e2e/polkadot-api-e2e.json

This file was deleted.

6 changes: 5 additions & 1 deletion jest.e2e.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
const commonConfig = require("./jest.config");

/** @type {import("ts-jest/dist/types").InitialOptionsTsJest} */
module.exports = { ...commonConfig, testMatch: ["**/?(*.)+(e2e).[jt]s?(x)"], testTimeout: 60_000 };
module.exports = {
...commonConfig,
testRegex: ["\\w+\\.(e2e).ts"],
testTimeout: 60_000,
};
27 changes: 11 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@
"fix": "yarn lint:fix && yarn format:fix",
"format": "prettier ./src ./client/src ./client/tests --check",
"format:fix": "prettier ./src ./client/src ./client/tests --write",
"generate:papi": "papi generate",
"generate:types": "echo \"declare const schema: $(cat env.faucet.config.json); export default schema;\" > env.faucet.config.json.d.ts",
"generate:papi:e2e": "papi generate --config e2e/polkadot-api-e2e.json",
"lint": "eslint ./src/ ./client/src ./client/tests --ext .js,.ts,.svelte",
"lint:fix": "eslint ./src/ ./client/src ./client/tests --ext .js,.ts,.svelte --fix",
"migrations:generate": "typeorm-ts-node-commonjs migration:generate -d src/db/dataSource.ts",
"migrations:run": "typeorm-ts-node-commonjs migration:run -d src/db/dataSource.ts",
"postinstall": "yarn generate:types",
"prebuild": "yarn generate:types",
"prebuild": "yarn generate:types && yarn generate:papi",
"prepare": "ts-patch install -s",
"start": "node ./build/src/start.js",
"e2e:zombienet": "rm -rf e2e/zombienet && npx --yes @zombienet/[email protected] --provider native --dir e2e/zombienet spawn e2e/zombienet.native.toml",
"test": "jest",
"test:e2e": "NODE_OPTIONS='--experimental-vm-modules --es-module-specifier-resolution=node' jest -c jest.e2e.config.js --runInBand --forceExit",
"typecheck": "tsc --noEmit"
Expand Down Expand Up @@ -50,26 +51,20 @@
},
"dependencies": {
"@eng-automation/js": "^1.0.3",
"@polkadot-api/cli": "^0.0.1-0027dd301d1d5a078e9c770a18e27aed76a66f50.1.0",
"@polkadot-api/client": "^0.0.1-0027dd301d1d5a078e9c770a18e27aed76a66f50.1.0",
"@polkadot-api/node-polkadot-provider": "^0.0.1-0027dd301d1d5a078e9c770a18e27aed76a66f50.1.0",
"@polkadot-api/ws-provider": "^0.0.1-0027dd301d1d5a078e9c770a18e27aed76a66f50.1.0",
"@polkadot/api": "^10.10.1",
"@polkadot/keyring": "^12.5.1",
"@polkadot/util": "^12.5.1",
"@polkadot/util-crypto": "^12.5.1",
"@polkadot/wasm-crypto": "^7.2.2",
"@polkadot/x-randomvalues": "^12.5.1",
"@polkadot-labs/hdkd": "^0.0.6",
"@polkadot-labs/hdkd-helpers": "^0.0.6",
"@types/cors": "^2.8.13",
"axios": "^1.6.0",
"bigfloat.js": "^3.0.1",
"blake2": "^5.0.0",
"body-parser": "^1.20.0",
"bs58": "^5.0.0",
"confmgr": "^1.0.8",
"cors": "^2.8.5",
"express": "4.19.2",
"matrix-js-sdk": "^26.1.0",
"pg": "^8.11.2",
"polkadot-api": "^0.7.0",
"prom-client": "^14.2.0",
"reflect-metadata": "^0.1.13",
"request": "^2.88.2",
Expand All @@ -91,11 +86,11 @@
"rxjs": "^7.8.1",
"simple-git-hooks": "^2.7.0",
"supertest": "^6.3.3",
"testcontainers": "^9.9.1",
"testcontainers": "v10.8.1",
"ts-jest": "^29.0.5",
"ts-node": "^10.9.1",
"ts-patch": "^2.1.0",
"typescript": "^4.9.3",
"typescript-transform-paths": "^3.4.6"
"ts-patch": "^3.1.2",
"typescript": "^5.3.2",
"typescript-transform-paths": "^3.4.7"
}
}
30 changes: 30 additions & 0 deletions polkadot-api.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"rococo": {
"chain": "rococo_v2_2",
"metadata": "src/papi/chains/data/rococo.scale"
},
"westend": {
"chain": "westend2",
"metadata": "src/papi/chains/data/westend.scale"
},
"e2e_relaychain": {
"wsUrl": "ws://127.0.0.1:9933",
"metadata": "src/papi/chains/data/e2e_relaychain.scale"
},
"e2e_parachain": {
"wsUrl": "ws://127.0.0.1:9934",
"metadata": "src/papi/chains/data/e2e_parachain.scale"
},
"versi": {
"wsUrl": "wss://versi-rpc-node-0.parity-versi.parity.io",
"metadata": "src/papi/chains/data/versi.scale"
},
"paseo": {
"wsUrl": "wss://paseo.rpc.amforc.com/",
"metadata": "src/papi/chains/data/paseo.scale"
},
"trappist": {
"wsUrl": "wss://rococo-trappist-rpc.polkadot.io/",
"metadata": "src/papi/chains/data/trappist.scale"
}
}
44 changes: 23 additions & 21 deletions src/bot/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { decodeAddress } from "@polkadot/keyring";
import * as mSDK from "matrix-js-sdk";
import { AccountId } from "polkadot-api";

import { config } from "../config";
import { getDripRequestHandlerInstance } from "../dripper/DripRequestHandler";
import polkadotActions from "../dripper/polkadot/PolkadotActions";
import { convertAmountToBn, convertBnAmountToNumber, formatAmount } from "../dripper/polkadot/utils";
import { isDripSuccessResponse } from "../guards";
import { logger } from "../logger";
import { getNetworkData } from "../networkData";
import { isAccountPrivileged } from "../utils";
import { config } from "src/config";
import { getDripRequestHandlerInstance } from "src/dripper/DripRequestHandler";
import polkadotActions from "src/dripper/polkadot/PolkadotActions";
import { convertAmountToBn, convertBnAmountToNumber, formatAmount } from "src/dripper/polkadot/utils";
import { isDripSuccessResponse } from "src/guards";
import { logger } from "src/logger";
import { getNetworkData } from "src/papi";
import { isAccountPrivileged } from "src/utils";

const dripRequestHandler = getDripRequestHandlerInstance(polkadotActions);

Expand Down Expand Up @@ -55,7 +55,7 @@ const printHelpMessage = (roomId: string, message = "") =>
`${message ? `${message} - ` : ""}The following commands are supported:
!balance - Get the faucet's balance.
!drip <Address>[:ParachainId] - Send ${
networkData.currency
networkData.data.currency
}s to <Address>, if the optional suffix \`:SomeParachainId\` is given a teleport will be issued.
!help - Print this message`,
);
Expand Down Expand Up @@ -99,17 +99,17 @@ bot.on(mSDK.RoomEvent.Timeline, (event: mSDK.MatrixEvent) => {

logger.debug(`Processing request from ${sender}`);

let dripAmount: bigint = convertAmountToBn(networkData.dripAmount);
let dripAmount: bigint = convertAmountToBn(networkData.data.dripAmount);
const [action, arg0, arg1] = body.split(" ");

if (action === "!version") {
sendMessage(roomId, `Current version: ${deployedRef}`);
} else if (action === "!balance") {
(async () => {
const balance = BigInt(await polkadotActions.getBalance());
const balance = await polkadotActions.getFaucetBalance();
const displayBalance = formatAmount(balance);

sendMessage(roomId, `The faucet has ${displayBalance} ${networkData.currency}s remaining.`);
sendMessage(roomId, `The faucet has ${displayBalance} ${networkData.data.currency}s remaining.`);
})().catch((e) => {
sendMessage(roomId, "An error occurred, please check the server logs.");
logger.error("⭕ An error occurred when checking the balance", e);
Expand All @@ -126,7 +126,8 @@ bot.on(mSDK.RoomEvent.Timeline, (event: mSDK.MatrixEvent) => {
logger.debug(`Processed receiver to address ${address} and parachain id ${parachain_id}`);

try {
decodeAddress(address);
// TODO: check this
AccountId().enc(address);
} catch (e) {
sendMessage(roomId, `${sender} provided an incompatible address.`);
return;
Expand All @@ -140,16 +141,16 @@ bot.on(mSDK.RoomEvent.Timeline, (event: mSDK.MatrixEvent) => {
// who have access to loki logs
if (Number.isNaN(dripAmount)) {
logger.error(
`⭕ Failed to convert drip amount: "${arg1}" to number, defaulting to ${networkData.dripAmount} ${networkData.currency}s`,
`⭕ Failed to convert drip amount: "${arg1}" to number, defaulting to ${networkData.data.dripAmount} ${networkData.data.currency}s`,
);
dripAmount = convertAmountToBn(networkData.dripAmount);
dripAmount = convertAmountToBn(networkData.data.dripAmount);
}

if (dripAmount <= 0) {
logger.error(
`⭕ Drip amount can't be less than 0, got ${dripAmount}, defaulting to ${networkData.dripAmount} ${networkData.currency}s`,
`⭕ Drip amount can't be less than 0, got ${dripAmount}, defaulting to ${networkData.data.dripAmount} ${networkData.data.currency}s`,
);
dripAmount = convertAmountToBn(networkData.dripAmount);
dripAmount = convertAmountToBn(networkData.data.dripAmount);
}
}

Expand Down Expand Up @@ -210,11 +211,12 @@ function formattedSuccessfulDripResponse(
formatted: string;
} {
const numberDripAmount = convertBnAmountToNumber(dripAmount);
const extrinsicLink = networkData.explorer !== null ? `${networkData.explorer}/extrinsic/${extrinsicHash}` : null;
const extrinsicLink =
networkData.data.explorer !== null ? `${networkData.data.explorer}/extrinsic/${extrinsicHash}` : null;

const messagePlain = `Sent ${sender} ${numberDripAmount} ${networkData.currency}s.
const messagePlain = `Sent ${sender} ${numberDripAmount} ${networkData.data.currency}s.
Extrinsic hash: ${extrinsicHash}`;
let messageHtml = `Sent ${sender} ${numberDripAmount} ${networkData.currency}s.`;
let messageHtml = `Sent ${sender} ${numberDripAmount} ${networkData.data.currency}s.`;
if (extrinsicLink !== null) {
messageHtml += `<br />Extrinsic hash: <a href="${extrinsicLink}">${extrinsicHash}</a>`;
} else {
Expand Down
20 changes: 11 additions & 9 deletions src/dripper/DripRequestHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,15 @@ import { hasDrippedToday, saveDrip } from "./dripperStorage";
import type { PolkadotActions } from "./polkadot/PolkadotActions";
import { Recaptcha } from "./Recaptcha";

const isParachainValid = (parachain: string): boolean => {
if (!parachain) {
return true;
}

const validateParachainId = (parachain: string): number | null => {
const id = Number.parseInt(parachain);
if (isNaN(id)) {
return false;
return null;
}
if (id < 999 || id > 10_000) {
return null;
}
return id > 999 && id < 10_000;
return id;
};

export class DripRequestHandler {
Expand All @@ -36,8 +35,11 @@ export class DripRequestHandler {

if (external && !(await this.recaptcha.validate(opts.recaptcha)))
return { error: "Captcha validation was unsuccessful" };
if (!isParachainValid(parachain_id))

const validatedParachainId = parachain_id ? validateParachainId(parachain_id) : null;
if (parachain_id && validatedParachainId === null) {
return { error: "Parachain invalid. Be sure to set a value between 1000 and 9999" };
}

const isAllowed = !(await hasDrippedToday(external ? { addr } : { username: opts.sender, addr }));
const isPrivileged = !external && isAccountPrivileged(opts.sender);
Expand All @@ -49,7 +51,7 @@ export class DripRequestHandler {
} else if (isAllowed && isAccountOverBalanceCap && !isPrivileged) {
return { error: `Requester's balance is over the faucet's balance cap` };
} else {
const sendTokensResult = await this.actions.sendTokens(addr, parachain_id, amount);
const sendTokensResult = await this.actions.sendTokens(addr, validatedParachainId, amount);

// hash is null if something wrong happened
if (isDripSuccessResponse(sendTokensResult)) {
Expand Down
Loading

0 comments on commit a266142

Please sign in to comment.