UNPKG

@nomiclabs/buidler

Version:

Buidler is an extensible developer tool that helps smart contract developers increase productivity by reliably bringing together the tools they want.

124 lines 7.62 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const provider_utils_1 = require("./provider-utils"); const wrapper_1 = require("./wrapper"); const DEFAULT_GAS_MULTIPLIER = 1; exports.GANACHE_GAS_MULTIPLIER = 5; function createFixedGasProvider(provider, gasLimit) { const rpcGasLimit = provider_utils_1.numberToRpcQuantity(gasLimit); return wrapper_1.wrapSend(provider, async (method, params) => { if (method === "eth_sendTransaction") { const tx = params[0]; if (tx !== undefined && tx.gas === undefined) { tx.gas = rpcGasLimit; } } return provider.send(method, params); }); } exports.createFixedGasProvider = createFixedGasProvider; function createFixedGasPriceProvider(provider, gasPrice) { const rpcGasPrice = provider_utils_1.numberToRpcQuantity(gasPrice); return wrapper_1.wrapSend(provider, async (method, params) => { if (method === "eth_sendTransaction") { const tx = params[0]; if (tx !== undefined && tx.gasPrice === undefined) { tx.gasPrice = rpcGasPrice; } } return provider.send(method, params); }); } exports.createFixedGasPriceProvider = createFixedGasPriceProvider; function createAutomaticGasProvider(provider, gasMultiplier = DEFAULT_GAS_MULTIPLIER) { const getMultipliedGasEstimation = createMultipliedGasEstimationGetter(); return wrapper_1.wrapSend(provider, async (method, params) => { if (method === "eth_sendTransaction") { const tx = params[0]; if (tx !== undefined && tx.gas === undefined) { tx.gas = await getMultipliedGasEstimation(provider, params, gasMultiplier); } } return provider.send(method, params); }); } exports.createAutomaticGasProvider = createAutomaticGasProvider; function createAutomaticGasPriceProvider(provider) { let gasPrice; return wrapper_1.wrapSend(provider, async (method, params) => { if (method === "eth_sendTransaction") { const tx = params[0]; if (tx !== undefined && tx.gasPrice === undefined) { if (gasPrice === undefined) { gasPrice = await provider.send("eth_gasPrice"); } tx.gasPrice = gasPrice; } } return provider.send(method, params); }); } exports.createAutomaticGasPriceProvider = createAutomaticGasPriceProvider; /** * This provider multiplies whatever gas estimation Ganache gives by [[GANACHE_GAS_MULTIPLIER]] * * NOTE: This bug was present at least in Ganache 6.4.x. * One way to test if the bug is still present is to check if the estimation to * run a deployment transaction with this data is high enough: * * 0x608060405234801561001057600080fd5b5060405161043e38038061043e8339810180604052602081101561003357600080fd5b81019080805164010000000081111561004b57600080fd5b8281019050602081018481111561006157600080fd5b815185600182028301116401000000008211171561007e57600080fd5b50509291905050506040516100929061010b565b604051809103906000f0801580156100ae573d6000803e3d6000fd5b506000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060019080519060200190610104929190610117565b50506101bc565b6088806103b683390190565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061015857805160ff1916838001178555610186565b82800160010185558215610186579182015b8281111561018557825182559160200191906001019061016a565b5b5090506101939190610197565b5090565b6101b991905b808211156101b557600081600090555060010161019d565b5090565b90565b6101eb806101cb6000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f86cc00914610030575b600080fd5b61003861003a565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166319ff1d216040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156100a357600080fd5b505af11580156100b7573d6000803e3d6000fd5b505050506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166319ff1d216040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561012457600080fd5b505af1158015610138573d6000803e3d6000fd5b505050506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166319ff1d216040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156101a557600080fd5b505af11580156101b9573d6000803e3d6000fd5b5050505056fea165627a7a723058203691efa02f6279a7b7eea9265988d2deaf417c2590c3103779c96b68e78463b700296080604052348015600f57600080fd5b50606b80601d6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806319ff1d2114602d575b600080fd5b60336035565b005b600560008190555056fea165627a7a72305820a00cf00e60c019ed83e0857faef9e9383880a5addd91429d30203771c82a4014002900000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000 */ function createGanacheGasMultiplierProvider(provider) { let isGanache; const getMultipliedGasEstimation = createMultipliedGasEstimationGetter(); return wrapper_1.wrapSend(provider, async (method, params) => { if (isGanache === undefined) { const clientVersion = await provider.send("web3_clientVersion"); isGanache = clientVersion.includes("TestRPC"); } if (method === "eth_estimateGas" && isGanache) { return getMultipliedGasEstimation(provider, params, exports.GANACHE_GAS_MULTIPLIER); } return provider.send(method, params); }); } exports.createGanacheGasMultiplierProvider = createGanacheGasMultiplierProvider; function createMultipliedGasEstimationGetter() { // We create this getter this way so this cache is recreated when the BRE // is reseted let cachedGasLimit; async function getBlockGasLimit(provider) { if (cachedGasLimit === undefined) { const latestBlock = await provider.send("eth_getBlockByNumber", [ "latest", false, ]); const fetchedGasLimit = provider_utils_1.rpcQuantityToNumber(latestBlock.gasLimit); // For future uses, we store a lower value in case the gas limit varies slightly cachedGasLimit = Math.floor(fetchedGasLimit * 0.95); return fetchedGasLimit; } return cachedGasLimit; } return async function getMultipliedGasEstimation(provider, params, gasMultiplier) { try { const realEstimation = await provider.send("eth_estimateGas", params); if (gasMultiplier === 1) { return realEstimation; } const normalGas = provider_utils_1.rpcQuantityToNumber(realEstimation); const gasLimit = await getBlockGasLimit(provider); const multiplied = Math.floor(normalGas * gasMultiplier); const gas = multiplied > gasLimit ? gasLimit - 1 : multiplied; return provider_utils_1.numberToRpcQuantity(gas); } catch (error) { if (error.message.toLowerCase().includes("execution error")) { const blockGasLimit = await getBlockGasLimit(provider); return provider_utils_1.numberToRpcQuantity(blockGasLimit); } // tslint:disable-next-line only-buidler-error throw error; } }; } //# sourceMappingURL=gas-providers.js.map