Skip to content

Commit 239749f

Browse files
committed
Modified the precheck to skip GAS_PRICE_TINY_BAR_BUFFER checks in case of fully subsidized transactions
Signed-off-by: Giuseppe Bertone <[email protected]>
1 parent 5e95ee8 commit 239749f

File tree

3 files changed

+56
-57
lines changed

3 files changed

+56
-57
lines changed

docs/configuration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ Unless you need to set a non-default value, it is recommended to only populate o
6868
| `IP_RATE_LIMIT_STORE` | null | Specifies the rate limit store to use for IP-based rate limiting: valid values are "LRU", "REDIS", with the possibility to be extended with a custom implementation (see [Store Selection](rate-limiting.md#store-selection)). If unset, falls back to Redis when `REDIS_ENABLED=true`, otherwise uses in-memory LRU. |
6969
| `JUMBO_TX_ENABLED` | "true" | Controls how large transactions are handled during `eth_sendRawTransaction`. When set to `true`, transactions up to 128KB can be sent directly to consensus nodes without using Hedera File Service (HFS), as long as contract bytecode doesn't exceed 24KB. When set to `false`, all transactions containing contract deployments use the traditional HFS approach. This feature leverages the increased transaction size limit to simplify processing of standard Ethereum transactions. |
7070
| `LIMIT_DURATION` | "60000" | The maximum duration in ms applied to IP-method based rate limits. |
71-
| `MAX_GAS_ALLOWANCE_HBAR` | "0" | The maximum amount, in hbars, that the JSON-RPC Relay is willing to pay to complete the transaction in case the senders don't provide enough funds to pay for their transactions. Please note, in case of fully subsidized transactions, the sender must set the gas price to `0` and the JSON-RPC Relay must configure both the `GAS_PRICE_TINY_BAR_BUFFER`, to a number big enough to cover the discrepancy between the base gas price and `0`, and the `MAX_GAS_ALLOWANCE_HBAR` parameters, with the max amount of HBARs the JSON-RPC Relay is willing to spend to execute the transaction. |
71+
| `MAX_GAS_ALLOWANCE_HBAR` | "0" | The maximum amount, in hbars, that the JSON-RPC Relay is willing to pay to complete the transaction in case the senders don't provide enough funds. Please note, in case of fully subsidized transactions, the sender must set the gas price to `0` and the JSON-RPC Relay must configure the `MAX_GAS_ALLOWANCE_HBAR` parameter high enough to cover the entire transaction cost. |
7272
| `MAX_TRANSACTION_FEE_THRESHOLD` | "15000000" | Used to set the max transaction fee. This is the HAPI fee which is paid by the relay operator account. |
7373
| `MIRROR_NODE_AGENT_CACHEABLE_DNS` | "true" | Flag to set if the mirror node agent should cacheable DNS lookups, using better-lookup library. |
7474
| `MIRROR_NODE_CONTRACT_RESULTS_LOGS_PG_MAX` | "200" | The maximum number of pages to be requested for contract results logs from the mirror node. (each page will contain a max of 100 results) |

packages/relay/src/lib/precheck.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,16 @@ export class Precheck {
162162
const txGasPrice = BigInt(tx.gasPrice || tx.maxFeePerGas! + tx.maxPriorityFeePerGas!);
163163

164164
// **notice: Pass gasPrice precheck if txGasPrice is greater than the minimum network's gas price value,
165-
// OR if the transaction is the deterministic deployment transaction (a special case).
165+
// OR if the transaction is the deterministic deployment transaction (a special case),
166+
// OR in case of fully subsidized transactions where gasPrice was set 0 by the user and the provider set a gas allowance
166167
// **explanation: The deterministic deployment transaction is pre-signed with a gasPrice value of only 10 hbars,
167168
// which is lower than the minimum gas price value in all Hedera network environments. Therefore,
168169
// this special case is exempt from the precheck in the Relay, and the gas price logic will be resolved at the Services level.
169-
const passes = txGasPrice >= networkGasPrice || Precheck.isDeterministicDeploymentTransaction(tx);
170+
// The same is true for fully subsidized transactions, where the precheck about the gasPrice is not needed anymore.
171+
const passes =
172+
txGasPrice >= networkGasPrice ||
173+
Precheck.isDeterministicDeploymentTransaction(tx) ||
174+
(txGasPrice === BigInt(0) && ConfigService.get('MAX_GAS_ALLOWANCE_HBAR') > 0);
170175

171176
if (!passes) {
172177
if (ConfigService.get('GAS_PRICE_TINY_BAR_BUFFER')) {

packages/server/tests/acceptance/rpc_batch1.spec.ts

Lines changed: 48 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1555,60 +1555,54 @@ describe('@api-batch-1 RPC Server Acceptance Tests', function () {
15551555
});
15561556

15571557
describe('Check subsidizing gas fees', async function () {
1558-
withOverriddenEnvsInMochaTest(
1559-
{
1560-
GAS_PRICE_TINY_BAR_BUFFER: 2000000000000,
1561-
MAX_GAS_ALLOWANCE_HBAR: 100,
1562-
},
1563-
() => {
1564-
it('should execute a pre EIP-1559 transaction with "eth_sendRawTransaction" and pays the total amount of the fees on behalf of the sender', async function () {
1565-
const balanceBefore = await relay.getBalance(accounts[2].wallet.address, 'latest', requestId);
1566-
1567-
const transaction = {
1568-
type: 1,
1569-
chainId: Number(CHAIN_ID),
1570-
nonce: await relay.getAccountNonce(accounts[2].wallet.address, requestId),
1571-
gasPrice: 0,
1572-
gasLimit: Constants.MAX_TRANSACTION_FEE_THRESHOLD,
1573-
data: '0x' + '00'.repeat(Constants.CONTRACT_CODE_SIZE_LIMIT),
1574-
};
1575-
const signedTx = await accounts[2].wallet.signTransaction(transaction);
1576-
const transactionHash = await relay.sendRawTransaction(signedTx, requestId);
1577-
const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId);
1578-
expect(info).to.have.property('contract_id');
1579-
expect(info.contract_id).to.not.be.null;
1580-
expect(info).to.have.property('created_contract_ids');
1581-
expect(info.created_contract_ids.length).to.be.equal(1);
1582-
1583-
const balanceAfter = await relay.getBalance(accounts[2].wallet.address, 'latest', requestId);
1584-
expect(balanceAfter).to.be.equal(balanceBefore);
1585-
});
1586-
1587-
it('should execute a post EIP-1559 transaction with "eth_sendRawTransaction" and pays the total amount of the fees on behalf of the sender', async function () {
1588-
const balanceBefore = await relay.getBalance(accounts[2].wallet.address, 'latest', requestId);
1589-
1590-
const transaction = {
1591-
type: 2,
1592-
chainId: Number(CHAIN_ID),
1593-
nonce: await relay.getAccountNonce(accounts[2].wallet.address, requestId),
1594-
maxPriorityFeePerGas: 0,
1595-
maxFeePerGas: 0,
1596-
gasLimit: Constants.MAX_TRANSACTION_FEE_THRESHOLD,
1597-
data: '0x' + '00'.repeat(Constants.CONTRACT_CODE_SIZE_LIMIT),
1598-
};
1599-
const signedTx = await accounts[2].wallet.signTransaction(transaction);
1600-
const transactionHash = await relay.sendRawTransaction(signedTx, requestId);
1601-
const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId);
1602-
expect(info).to.have.property('contract_id');
1603-
expect(info.contract_id).to.not.be.null;
1604-
expect(info).to.have.property('created_contract_ids');
1605-
expect(info.created_contract_ids.length).to.be.equal(1);
1606-
1607-
const balanceAfter = await relay.getBalance(accounts[2].wallet.address, 'latest', requestId);
1608-
expect(balanceAfter).to.be.equal(balanceBefore);
1609-
});
1610-
},
1611-
);
1558+
withOverriddenEnvsInMochaTest({ MAX_GAS_ALLOWANCE_HBAR: 100 }, () => {
1559+
it('should execute a pre EIP-1559 transaction with "eth_sendRawTransaction" and pays the total amount of the fees on behalf of the sender', async function () {
1560+
const balanceBefore = await relay.getBalance(accounts[2].wallet.address, 'latest', requestId);
1561+
1562+
const transaction = {
1563+
type: 1,
1564+
chainId: Number(CHAIN_ID),
1565+
nonce: await relay.getAccountNonce(accounts[2].wallet.address, requestId),
1566+
gasPrice: 0,
1567+
gasLimit: Constants.MAX_TRANSACTION_FEE_THRESHOLD,
1568+
data: '0x' + '00'.repeat(Constants.CONTRACT_CODE_SIZE_LIMIT),
1569+
};
1570+
const signedTx = await accounts[2].wallet.signTransaction(transaction);
1571+
const transactionHash = await relay.sendRawTransaction(signedTx, requestId);
1572+
const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId);
1573+
expect(info).to.have.property('contract_id');
1574+
expect(info.contract_id).to.not.be.null;
1575+
expect(info).to.have.property('created_contract_ids');
1576+
expect(info.created_contract_ids.length).to.be.equal(1);
1577+
1578+
const balanceAfter = await relay.getBalance(accounts[2].wallet.address, 'latest', requestId);
1579+
expect(balanceAfter).to.be.equal(balanceBefore);
1580+
});
1581+
1582+
it('should execute a post EIP-1559 transaction with "eth_sendRawTransaction" and pays the total amount of the fees on behalf of the sender', async function () {
1583+
const balanceBefore = await relay.getBalance(accounts[2].wallet.address, 'latest', requestId);
1584+
1585+
const transaction = {
1586+
type: 2,
1587+
chainId: Number(CHAIN_ID),
1588+
nonce: await relay.getAccountNonce(accounts[2].wallet.address, requestId),
1589+
maxPriorityFeePerGas: 0,
1590+
maxFeePerGas: 0,
1591+
gasLimit: Constants.MAX_TRANSACTION_FEE_THRESHOLD,
1592+
data: '0x' + '00'.repeat(Constants.CONTRACT_CODE_SIZE_LIMIT),
1593+
};
1594+
const signedTx = await accounts[2].wallet.signTransaction(transaction);
1595+
const transactionHash = await relay.sendRawTransaction(signedTx, requestId);
1596+
const info = await mirrorNode.get(`/contracts/results/${transactionHash}`, requestId);
1597+
expect(info).to.have.property('contract_id');
1598+
expect(info.contract_id).to.not.be.null;
1599+
expect(info).to.have.property('created_contract_ids');
1600+
expect(info.created_contract_ids.length).to.be.equal(1);
1601+
1602+
const balanceAfter = await relay.getBalance(accounts[2].wallet.address, 'latest', requestId);
1603+
expect(balanceAfter).to.be.equal(balanceBefore);
1604+
});
1605+
});
16121606
});
16131607

16141608
describe('Prechecks', async function () {

0 commit comments

Comments
 (0)