Skip to content
This repository has been archived by the owner on Mar 24, 2023. It is now read-only.

feat(v0): add minimal gasPrice env #611

Merged
merged 3 commits into from
Feb 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ lib/
packages/api-server/allowed-addresses.json
crates/**/target
target
indexer-config.toml
indexer-config.toml

*.env
*.cpuprofile
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ ENABLE_CACHE_POLY_EXECUTE_RAW_L2Tx=<optional, enable poly_executeRawL2Transactio
LOG_LEVEL=<optional, allowed value: `debug` / `info` / `warn` / `error`, default to `debug` in development, and default to `info` in production>
LOG_FORMAT=<optional, allowed value: `json`>
MAX_SOCKETS=<optional, max number of httpAgent sockets per host for web3 connecting to godwoken, default to 10>
MIN_GAS_PRICE=<optional, decimal number, the minimal gas price required in wei>
EOF

$ yarn
Expand Down
1 change: 1 addition & 0 deletions packages/api-server/src/base/env-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const envConfig = {
),
logLevel: getOptional("LOG_LEVEL"),
logFormat: getOptional("LOG_FORMAT"),
minGasPrice: getOptional("MIN_GAS_PRICE"),
};

function getRequired(name: string): string {
Expand Down
3 changes: 3 additions & 0 deletions packages/api-server/src/convert-tx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { rlp } from "ethereumjs-util";
import keccak256 from "keccak256";
import * as secp256k1 from "secp256k1";
import { logger } from "./base/logger";
import { verifyGasPrice } from "./methods/validator";

export const EMPTY_ETH_ADDRESS = "0x" + "00".repeat(20);

Expand Down Expand Up @@ -128,6 +129,8 @@ function encodePolyjuiceTransaction(tx: PolyjuiceTransaction) {
async function parseRawTransactionData(rawTx: PolyjuiceTransaction, rpc: RPC) {
const { nonce, gasPrice, gasLimit, to: toA, value, data, v, r, s } = rawTx;

verifyGasPrice(gasPrice === "0x" ? "0x0" : gasPrice, 0);

let real_v = "0x00";
if (+v % 2 === 0) {
real_v = "0x01";
Expand Down
1 change: 0 additions & 1 deletion packages/api-server/src/methods/constant.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// source: https://github.com/nervosnetwork/godwoken-polyjuice/blob/main/docs/EVM-compatible.md
export const POLY_MAX_BLOCK_GAS_LIMIT = 12500000;
export const POLY_MAX_TRANSACTION_GAS_LIMIT = 12500000;
export const POLY_MIN_GAS_PRICE = 0;
export const POLY_BLOCK_DIFFICULTY = BigInt("2500000000000000");

export const DEFAULT_EMPTY_ETH_ADDRESS = `0x${"0".repeat(40)}`;
Expand Down
7 changes: 4 additions & 3 deletions packages/api-server/src/methods/modules/eth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,7 @@ export class Eth {
}

let medianGasPrice = await this.query.getMedianGasPrice();
// set min to 1
const minGasPrice = BigInt(1);
const minGasPrice = BigInt(envConfig.minGasPrice || 0);
if (medianGasPrice < minGasPrice) {
medianGasPrice = minGasPrice;
}
Expand Down Expand Up @@ -1375,7 +1374,9 @@ async function buildEthCallTx(
const fromAddress = txCallObj.from || envConfig.defaultFromAddress;
const toAddress = txCallObj.to || "0x" + "00".repeat(20);
const gas = txCallObj.gas || "0x1000000";
const gasPrice = txCallObj.gasPrice || "0x1";
const gasPrice =
txCallObj.gasPrice ||
"0x" + BigInt(envConfig.minGasPrice || 0).toString(16);
const value = txCallObj.value || "0x0";
const data = txCallObj.data || "0x0";
let fromId: number | undefined;
Expand Down
24 changes: 23 additions & 1 deletion packages/api-server/src/methods/modules/gw.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import { parseGwRpcError } from "../gw-error";
import { RPC } from "@godwoken-web3/godwoken";
import { middleware } from "../validator";
import { middleware, verifyGasPrice } from "../validator";
import { HexNumber } from "@ckb-lumos/base";
import { Store } from "../../cache/store";
import { envConfig } from "../../base/env-config";
import { CACHE_EXPIRED_TIME_MILSECS, GW_RPC_KEY } from "../../cache/constant";
import { logger } from "../../base/logger";
import {
L2Transaction,
RawL2Transaction,
} from "@godwoken-web3/godwoken/schemas";
import { Reader } from "@ckb-lumos/toolkit";
import { decodeArgs } from "@polyjuice-provider/base";

export class Gw {
private rpc: RPC;
Expand Down Expand Up @@ -305,6 +311,14 @@ export class Gw {
*/
async execute_raw_l2transaction(args: any[]) {
try {
// validate minimal gas price
const serializedRawL2Tx = args[0];
const rawL2Tx = new RawL2Transaction(new Reader(serializedRawL2Tx));
const { gas_price } = decodeArgs(
new Reader(rawL2Tx.getArgs().raw()).serializeJson()
);
verifyGasPrice(gas_price === "0x" ? "0x0" : gas_price, 0);

args[1] = formatHexNumber(args[1]);

const result = await this.readonlyRpc.gw_execute_raw_l2transaction(
Expand All @@ -323,6 +337,14 @@ export class Gw {
*/
async submit_l2transaction(args: any[]) {
try {
// validate minimal gas price
const l2Tx = new L2Transaction(new Reader(args[0]));
const polyArgs = new Reader(
l2Tx.getRaw().getArgs().raw()
).serializeJson();
const { gas_price } = decodeArgs(polyArgs);
verifyGasPrice(gas_price === "0x" ? "0x0" : gas_price, 0);

const result = await this.rpc.gw_submit_l2transaction(...args);
return result;
} catch (error) {
Expand Down
12 changes: 11 additions & 1 deletion packages/api-server/src/methods/modules/poly.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { middleware, validators } from "../validator";
import { middleware, validators, verifyGasPrice } from "../validator";
import { Hash, HexNumber, Address, HexString } from "@ckb-lumos/base";
import { toHexNumber, Uint64 } from "../../base/types/uint";
import { envConfig } from "../../base/env-config";
Expand Down Expand Up @@ -86,6 +86,11 @@ export class Poly {
const txWithAddressMapping: L2TransactionWithAddressMapping =
deserializeL2TransactionWithAddressMapping(data);
const l2Tx = txWithAddressMapping.tx;

// validate minimal gas price
const { gas_price } = decodeArgs(l2Tx.raw.args);
verifyGasPrice(gas_price === "0x" ? "0x0" : gas_price, 0);

const result = await this.rpc.submitL2Transaction(l2Tx);
// if result is fine, then tx is legal, we can start thinking to store the address mapping
await saveAddressMapping(this.query, this.rpc, txWithAddressMapping);
Expand Down Expand Up @@ -145,6 +150,11 @@ export class Poly {
const txWithAddressMapping: RawL2TransactionWithAddressMapping =
deserializeRawL2TransactionWithAddressMapping(serializeRawL2Tx);
const rawL2Tx = txWithAddressMapping.raw_tx;

// validate minimal gas price
const { gas_price } = decodeArgs(rawL2Tx.args);
verifyGasPrice(gas_price === "0x" ? "0x0" : gas_price, 0);

const jsonResult = await this.rpc.executeRawL2Transaction(
rawL2Tx,
blockNumber
Expand Down
14 changes: 14 additions & 0 deletions packages/api-server/src/methods/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { validateHexNumber, validateHexString } from "../util";
import { BlockParameter } from "./types";
import { logger } from "../base/logger";
import { InvalidParamsError, RpcError } from "./error";
import { HexString } from "@ckb-lumos/base";
import { envConfig } from "../base/env-config";

/**
* middleware for parameters validation
Expand Down Expand Up @@ -374,3 +376,15 @@ function validateAddress(address: string): boolean {
function invalidParamsError(index: number, message: string): void {
throw new InvalidParamsError(`invalid argument ${index}: ${message}`);
}

export function verifyGasPrice(gasPrice: HexString, index: number) {
verifyHexNumber(gasPrice, index);

if (envConfig.minGasPrice != null && +gasPrice < +envConfig.minGasPrice) {
return invalidParamsError(
index,
`minimal gas price ${+envConfig.minGasPrice} required. got ${+gasPrice}`
);
}
return undefined;
}