Skip to content

Conversation

@MilanKomsa
Copy link
Contributor

@MilanKomsa MilanKomsa commented Dec 15, 2025

Note

Adds smart gas pricing via eth_feeHistory with optional buffer and overhauls token allowance to approve a threshold; wires new blockchain params.

  • Blockchain service (services/blockchain-service/blockchain-service-base.js):
    • Gas pricing:
      • Introduces getSmartGasPrice using EIP-1559 eth_feeHistory with fallback to network/default.
      • Adds helpers: getFeeHistory, applyGasPriceBuffer, estimateGasPriceFromFeeHistory; uses FEE_HISTORY_BLOCK_COUNT.
      • Transaction prep now uses blockchain.gasPrice ?? getSmartGasPrice(...).
    • Allowance flow:
      • Adds needsMoreAllowance and maxAllowancePerTransaction.
      • Replaces increment-by-gap with approve(allowanceThreshold) (uses blockchain.maxAllowance or wallet balance).
      • Removes rollback on failure; logs error in createKnowledgeCollection.
  • Input/config (services/input-service.js, constants/constants.js):
    • Plumbs new blockchain options: maxAllowance, gasPriceBufferPercent, retryTxGasPriceMultiplier (default via DEFAULT_PARAMETERS.RETRY_TX_GAS_PRICE_MULTIPLIER).
    • Exports FEE_HISTORY_BLOCK_COUNT constant.

Written by Cursor Bugbot for commit 8877fdb. This will update automatically on new commits. Configure here.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is being reviewed by Cursor Bugbot

Details

Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

// Theoretically this should never happen
gasPrice = Math.round(
(blockchain.gasPrice || (await this.getNetworkGasPrice(blockchain))) * 1.2,
(blockchain.gasPrice || (await this.getSmartGasPrice(blockchain))) * 3,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this hardcoded? I thought we agreed that this should be a multiplier passed by the user and use 3 as a sensible default?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is multiplier for exponential on retry, i created a user config for multiplier of regular transaction, ill make this configurable also

}

let finalGasPrice;
if (blockchain.MAXGASPRICE) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this logic all over the place? I have a feeling that we are leaking the implementation details a bit?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its all in same file, want me to move this within inner function?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's remove this for now, and have it as a separate PR @MilanKomsa

}

let finalGasPrice;
if (blockchain.MAXGASPRICE) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's remove this for now, and have it as a separate PR @MilanKomsa

Comment on lines 189 to 225
/*if (blockchain.previousTxGasPrice && blockchain.retryTx) {
// Increase previous tx gas price by retryTxGasPriceMultiplier
gasPrice = Math.round(blockchain.previousTxGasPrice * blockchain.retryTxGasPriceMultiplier);
} else if (blockchain.forceReplaceTxs) {
// Get the current transaction count (nonce) of the wallet, including pending transactions
const currentNonce = await web3Instance.eth.getTransactionCount(publicKey, 'pending');
// Get the transaction count of the wallet excluding pending transactions
const confirmedNonce = await web3Instance.eth.getTransactionCount(publicKey, 'latest');
// If there are any pending transactions
if (currentNonce > confirmedNonce) {
const pendingBlock = await web3Instance.eth.getBlock('pending', true);
// Search for pending tx in the pending block
const pendingTx = Object.values(pendingBlock.transactions).find(
(tx) =>
tx.from.toLowerCase() === publicKey.toLowerCase() &&
tx.nonce === confirmedNonce,
);
if (pendingTx) {
// If found, increase gas price of pending tx by 20%
gasPrice = Math.round(Number(pendingTx.gasPrice) * 1.2);
// If found, increase gas price of pending tx by retryTxGasPriceMultiplier
gasPrice = Math.round(Number(pendingTx.gasPrice) * blockchain.retryTxGasPriceMultiplier);
} else {
// If not found, use default/network gas price increased by 20%
// If not found, use default/network gas price increased by retryTxGasPriceMultiplier
// Theoretically this should never happen
gasPrice = Math.round(
(blockchain.gasPrice || (await this.getNetworkGasPrice(blockchain))) * 1.2,
(blockchain.gasPrice || (await this.getSmartGasPrice(blockchain))) * blockchain.retryTxGasPriceMultiplier,
);
}
} else {
gasPrice = blockchain.gasPrice || (await this.getNetworkGasPrice(blockchain));
gasPrice = blockchain.gasPrice || (await this.getSmartGasPrice(blockchain));
}
} else {
gasPrice = blockchain.gasPrice || (await this.getNetworkGasPrice(blockchain));
}
gasPrice = blockchain.gasPrice || (await this.getSmartGasPrice(blockchain));
}*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this commented out, do we have the retry logic anywhere else?
Can we remove the previousTxGasPrice and retryTx flags to simplify the code then?

gasPrice = blockchain.gasPrice || (await this.getNetworkGasPrice(blockchain));
}
gasPrice = blockchain.gasPrice || (await this.getSmartGasPrice(blockchain));
}*/
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: forceReplaceTxs configuration option is now ignored

The forceReplaceTxs option is still accepted in the input service and included in the blockchain config, but the entire code block that handles this feature (lines 193-223) is now commented out. Users who configure forceReplaceTxs to replace pending transactions with higher gas prices will find this feature silently no longer works.

Additional Locations (1)

Fix in Cursor Fix in Web

const retryTxGasPriceMultiplier =
options.blockchain?.retryTxGasPriceMultiplier ??
this.config.blockchain?.retryTxGasPriceMultiplier ??
DEFAULT_PARAMETERS.RETRY_TX_GAS_PRICE_MULTIPLIER; // e.g., 1.2
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: New retryTxGasPriceMultiplier option is dead code

A new retryTxGasPriceMultiplier configuration option is added along with a default constant, but the only code that would use this value is inside a commented-out block in prepareTransaction. This option has no effect and cannot function until the commented code is re-enabled.

Additional Locations (1)

Fix in Cursor Fix in Web


const maxAllowance =
options.blockchain?.maxAllowance ?? this.config.blockchain?.maxAllowance ?? undefined;
const bufferPercent =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's name this variable "gasPriceBufferPercent" or similar, so it's obvious what this buffer is for

in the words of late Phil Karlton "There are only two hard things in Computer Science: cache invalidation and naming things."

SIMULATE_TXS: false,
FORCE_REPLACE_TXS: false,
GAS_LIMIT_MULTIPLIER: 1,
BUFFER_PERCENT: 10,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's name this variable "GAS_PRICE_BUFFER_PERCENT" or similar, so it's obvious what this buffer is for

in the words of late Phil Karlton "There are only two hard things in Computer Science: cache invalidation and naming things."

gasPrice = blockchain.gasPrice || (await this.getNetworkGasPrice(blockchain));
}
gasPrice = blockchain.gasPrice || (await this.getSmartGasPrice(blockchain));
}*/
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Commented out code should have been deleted

A large block of code (lines 188-225) is commented out instead of being removed. The PR discussion explicitly asks "I guess we remove all this commented out code?" suggesting this commented code was supposed to be deleted entirely, not left in place. Leaving commented-out code in production creates maintenance burden and confusion about what the code is supposed to do.

Fix in Cursor Fix in Web

gasPrice = blockchain.gasPrice || (await this.getSmartGasPrice(blockchain));
}*/

const gasPrice = blockchain.gasPrice ?? (await this.getSmartGasPrice(blockchain));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Retry transaction gas price logic is now broken

The retry transaction gas price feature is broken. In node-blockchain-service.js, retry logic still sets blockchain.retryTx = true and blockchain.previousTxGasPrice when a transaction needs to be retried. However, prepareTransaction now ignores these values entirely and just uses blockchain.gasPrice ?? getSmartGasPrice(). The retryTxGasPriceMultiplier config is added to input-service.js and constants but never used, making retried transactions fail with the same gas price that previously failed.

Additional Locations (1)

Fix in Cursor Fix in Web

@MilanKomsa MilanKomsa merged commit 88aaddc into v8/develop Dec 16, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants