Commit 400d81fb authored by mergify[bot]'s avatar mergify[bot] Committed by GitHub

Merge pull request #4304 from ethereum-optimism/sc/ctb-clean-advanced-contract

maint(ctb): clean up getAdvancedContract
parents 80107e98 e72b44d2
...@@ -59,8 +59,8 @@ export const deploy = async ({ ...@@ -59,8 +59,8 @@ export const deploy = async ({
await hre.ethers.provider.waitForTransaction(result.transactionHash) await hre.ethers.provider.waitForTransaction(result.transactionHash)
// Create the contract object to return. // Create the contract object to return.
const created = getAdvancedContract({ const created = asAdvancedContract({
hre, confirmations: hre.deployConfig.numDeployConfirmations,
contract: new Contract( contract: new Contract(
result.address, result.address,
iface !== undefined iface !== undefined
...@@ -81,18 +81,19 @@ export const deploy = async ({ ...@@ -81,18 +81,19 @@ export const deploy = async ({
} }
/** /**
* Returns a version of the contract object which modifies all of the input contract's methods to: * Returns a version of the contract object which modifies all of the input contract's methods to
* 1. Waits for a confirmed receipt with more than numDeployConfirmations confirmations. * automatically await transaction receipts and confirmations. Will also throw if we timeout while
* 2. Include simple resubmission logic, ONLY for Kovan, which appears to drop transactions. * waiting for a transaction to be included in a block.
* *
* @param opts Options for the contract. * @param opts Options for the contract.
* @param opts.hre HardhatRuntimeEnvironment. * @param opts.hre HardhatRuntimeEnvironment.
* @param opts.contract Contract to wrap. * @param opts.contract Contract to wrap.
* @returns Wrapped contract object. * @returns Wrapped contract object.
*/ */
export const getAdvancedContract = (opts: { export const asAdvancedContract = (opts: {
hre: HardhatRuntimeEnvironment
contract: Contract contract: Contract
confirmations?: number
gasPrice?: number
}): Contract => { }): Contract => {
// Temporarily override Object.defineProperty to bypass ether's object protection. // Temporarily override Object.defineProperty to bypass ether's object protection.
const def = Object.defineProperty const def = Object.defineProperty
...@@ -114,32 +115,25 @@ export const getAdvancedContract = (opts: { ...@@ -114,32 +115,25 @@ export const getAdvancedContract = (opts: {
for (const fnName of Object.keys(contract.functions)) { for (const fnName of Object.keys(contract.functions)) {
const fn = contract[fnName].bind(contract) const fn = contract[fnName].bind(contract)
;(contract as any)[fnName] = async (...args: any) => { ;(contract as any)[fnName] = async (...args: any) => {
// We want to use the gas price that has been configured at the beginning of the deployment. // We want to use the configured gas price but we need to set the gas price to zero if we're
// However, if the function being triggered is a "constant" (static) function, then we don't // triggering a static function.
// want to provide a gas price because we're prone to getting insufficient balance errors. let gasPrice = opts.gasPrice
let gasPrice: number | undefined
try {
gasPrice = opts.hre.deployConfig.gasPrice
} catch (err) {
// Fine, no gas price
}
if (contract.interface.getFunction(fnName).constant) { if (contract.interface.getFunction(fnName).constant) {
gasPrice = 0 gasPrice = 0
} }
// Now actually trigger the transaction (or call).
const tx = await fn(...args, { const tx = await fn(...args, {
gasPrice, gasPrice,
}) })
// Meant for static calls, we don't need to wait for anything, we get the result right away.
if (typeof tx !== 'object' || typeof tx.wait !== 'function') { if (typeof tx !== 'object' || typeof tx.wait !== 'function') {
return tx return tx
} }
// Special logic for: // Wait for the transaction to be included in a block and wait for the specified number of
// (1) handling confirmations // deployment confirmations.
// (2) handling an issue on Kovan specifically where transactions get dropped for no
// apparent reason.
const maxTimeout = 120 const maxTimeout = 120
let timeout = 0 let timeout = 0
while (true) { while (true) {
...@@ -147,16 +141,10 @@ export const getAdvancedContract = (opts: { ...@@ -147,16 +141,10 @@ export const getAdvancedContract = (opts: {
const receipt = await contract.provider.getTransactionReceipt(tx.hash) const receipt = await contract.provider.getTransactionReceipt(tx.hash)
if (receipt === null) { if (receipt === null) {
timeout++ timeout++
if (timeout > maxTimeout && opts.hre.network.name === 'kovan') { if (timeout > maxTimeout) {
// Special resubmission logic ONLY required on Kovan. throw new Error('timeout exceeded waiting for txn to be mined')
console.log(
`WARNING: Exceeded max timeout on transaction. Attempting to submit transaction again...`
)
return contract[fnName](...args)
} }
} else if ( } else if (receipt.confirmations >= (opts.confirmations || 0)) {
receipt.confirmations >= opts.hre.deployConfig.numDeployConfirmations
) {
return tx return tx
} }
} }
...@@ -204,8 +192,8 @@ export const getContractFromArtifact = async ( ...@@ -204,8 +192,8 @@ export const getContractFromArtifact = async (
} }
} }
return getAdvancedContract({ return asAdvancedContract({
hre, confirmations: hre.deployConfig.numDeployConfirmations,
contract: new hre.ethers.Contract( contract: new hre.ethers.Contract(
artifact.address, artifact.address,
iface, iface,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment