Skip to content

Commit

Permalink
use safe storage for gas estimation
Browse files Browse the repository at this point in the history
  • Loading branch information
shunjizhan committed Jan 16, 2024
1 parent e67d357 commit 02045f7
Showing 1 changed file with 13 additions and 12 deletions.
25 changes: 13 additions & 12 deletions packages/eth-providers/src/base-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -930,7 +930,7 @@ export abstract class BaseProvider extends AbstractProvider {
? await this._getBlockHash(blockTag)
: undefined; // if blockTag is latest, avoid explicit blockhash for better performance

const { usedGas, gasLimit, usedStorage } = await this.estimateResources(transaction, blockHash);
const { usedGas, gasLimit, safeStorage } = await this.estimateResources(transaction, blockHash);

const tx = await resolveProperties(transaction);
const data = tx.data?.toString() ?? '0x';
Expand All @@ -939,7 +939,7 @@ export abstract class BaseProvider extends AbstractProvider {
data,
toBN(BigNumber.from(tx.value ?? 0)),
toBN(gasLimit),
toBN(usedStorage.isNegative() ? 0 : usedStorage),
toBN(safeStorage),
accessListify(tx.accessList ?? []),
] as const;

Expand All @@ -952,8 +952,8 @@ export abstract class BaseProvider extends AbstractProvider {
let txFee = await this._estimateGasCost(extrinsic, blockHash);
txFee = txFee.mul(gasLimit).div(usedGas); // scale it to the same ratio when estimate passing gasLimit

if (usedStorage.gt(0)) {
const storageFee = usedStorage.mul(this._getGasConsts().storageDepositPerByte);
if (safeStorage.gt(0)) {
const storageFee = safeStorage.mul(this._getGasConsts().storageDepositPerByte);
txFee = txFee.add(storageFee);
}

Expand All @@ -963,7 +963,7 @@ export abstract class BaseProvider extends AbstractProvider {

const tokenTransferSelector = '0xa9059cbb'; // transfer(address,uint256)
const isTokenTransfer = hexlify(await transaction.data ?? '0x').startsWith(tokenTransferSelector);
return encodeGasLimit(txFee, gasPrice, gasLimit, usedStorage, isTokenTransfer);
return encodeGasLimit(txFee, gasPrice, gasLimit, safeStorage, isTokenTransfer);
};

_estimateGasCost = async (
Expand Down Expand Up @@ -1009,7 +1009,7 @@ export abstract class BaseProvider extends AbstractProvider {
gasLimit: BigNumber;
}> => {
if (!gasLimit || !storageLimit) {
const { gasLimit: gas, usedStorage: storage } = await this.estimateResources(transaction);
const { gasLimit: gas, safeStorage: storage } = await this.estimateResources(transaction);
gasLimit = gasLimit ?? gas;
storageLimit = storageLimit ?? storage;
}
Expand Down Expand Up @@ -1095,7 +1095,7 @@ export abstract class BaseProvider extends AbstractProvider {
): Promise<{
usedGas: BigNumber;
gasLimit: BigNumber;
usedStorage: BigNumber;
safeStorage: BigNumber;
}> => {
const ethTx = await getTransactionRequest(transaction);

Expand Down Expand Up @@ -1144,7 +1144,7 @@ export abstract class BaseProvider extends AbstractProvider {
await this._ethCall({
...txRequest,
gasLimit,
});
}, blockHash);
} catch {
gasAlreadyWorks = false;
}
Expand All @@ -1160,7 +1160,7 @@ export abstract class BaseProvider extends AbstractProvider {
await this._ethCall({
...txRequest,
gasLimit: mid,
});
}, blockHash);
highest = mid;

if ((prevHighest - highest) / prevHighest < 0.1) break;
Expand All @@ -1179,10 +1179,11 @@ export abstract class BaseProvider extends AbstractProvider {
gasLimit = highest;
}

const safeStorage = Math.floor((Math.max(usedStorage, 0) + 64) * 1.1);
return {
usedGas: BigNumber.from(usedGas), // actual used gas
gasLimit: BigNumber.from(gasLimit), // gasLimit to pass execution
usedStorage: BigNumber.from(usedStorage),
usedGas: BigNumber.from(usedGas), // actual used gas
gasLimit: BigNumber.from(gasLimit), // gasLimit to pass execution
safeStorage: BigNumber.from(safeStorage), // slightly over estimated storage to be safer
};
};

Expand Down

0 comments on commit 02045f7

Please sign in to comment.