-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move logic from hardhat patches (#11)
- Loading branch information
Showing
27 changed files
with
1,664 additions
and
4,669 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@nomiclabs/hardhat-waffle": patch | ||
--- | ||
|
||
Introduce skipEstimateGas and injectCallHistory fields to hardhat config |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import type { RecordedCall } from "@ethereum-waffle/provider"; | ||
import { utils } from "ethers"; | ||
|
||
/** | ||
* Injects call history into hardhat provider, | ||
* making it possible to use matchers like calledOnContract | ||
*/ | ||
|
||
class CallHistory { | ||
public recordedCalls: RecordedCall[] = []; | ||
|
||
public addUniqueCall(call: RecordedCall) { | ||
if ( | ||
this.recordedCalls.find( | ||
(c) => c.address === call.address && c.data === call.data | ||
) === undefined | ||
) { | ||
this.recordedCalls.push(call); | ||
} | ||
} | ||
|
||
public clearAll() { | ||
this.recordedCalls = []; | ||
} | ||
} | ||
|
||
function toRecordedCall(message: any): RecordedCall { | ||
return { | ||
address: message.to?.buf | ||
? utils.getAddress(utils.hexlify(message.to.buf)) | ||
: undefined, | ||
data: message.data ? utils.hexlify(message.data) : "0x", | ||
}; | ||
} | ||
|
||
function getHardhatVMEventEmitter(hardhatWaffleProvider: any) { | ||
const vm = | ||
hardhatWaffleProvider?._hardhatNetwork.provider?._wrapped._wrapped?._wrapped | ||
?._node?._vmTracer?._vm; | ||
|
||
/** | ||
* There were changes related to the location of event emitter introduced | ||
* in Hardhat version 2.11.0. | ||
*/ | ||
return vm?.evm?.events ?? vm; | ||
} | ||
|
||
let injected = false; | ||
|
||
export const injectCallHistory = (hardhatWaffleProvider: any) => { | ||
if (injected) { | ||
return; | ||
} | ||
|
||
const callHistory = new CallHistory(); | ||
hardhatWaffleProvider.clearCallHistory = () => { | ||
callHistory.clearAll(); | ||
}; | ||
|
||
let beforeMessageListener: (message: any) => void | undefined; | ||
const init = | ||
hardhatWaffleProvider?._hardhatNetwork?.provider?._wrapped?._wrapped | ||
?._wrapped?._init; | ||
if (!init) { | ||
throw new Error("Could not inject call history into hardhat provider"); | ||
} | ||
hardhatWaffleProvider._hardhatNetwork.provider._wrapped._wrapped._wrapped._init = | ||
async function () { | ||
await init.apply(this); | ||
if (typeof beforeMessageListener === "function") { | ||
// has to be here because of weird behaviour of init function, which requires us to re-register the handler. | ||
getHardhatVMEventEmitter(hardhatWaffleProvider)?.off?.( | ||
"beforeMessage", | ||
beforeMessageListener | ||
); | ||
} | ||
beforeMessageListener = (message: any) => { | ||
callHistory.addUniqueCall(toRecordedCall(message)); | ||
}; | ||
hardhatWaffleProvider.callHistory = callHistory.recordedCalls; | ||
getHardhatVMEventEmitter(hardhatWaffleProvider)?.on?.( | ||
"beforeMessage", | ||
beforeMessageListener | ||
); | ||
}; | ||
|
||
injected = true; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { BigNumber } from "ethers"; | ||
|
||
let processRequest: any; | ||
|
||
export function skipEstimateGas( | ||
hardhatWaffleProvider: any, | ||
estimateResult: string | ||
) { | ||
let estimateGasResult: BigNumber; | ||
try { | ||
estimateGasResult = BigNumber.from(estimateResult); | ||
} catch { | ||
throw new Error( | ||
`The value of the skipEstimateGas (${estimateResult}) in \n` + | ||
"hardhat config property must be a valid BigNumber string" | ||
); | ||
} | ||
const init = | ||
hardhatWaffleProvider._hardhatNetwork.provider._wrapped._wrapped._wrapped | ||
._init; | ||
hardhatWaffleProvider._hardhatNetwork.provider._wrapped._wrapped._wrapped._init = | ||
async function () { | ||
await init.apply(this); | ||
if ( | ||
getHardhatVMEventEmitter(hardhatWaffleProvider)?.listenerCount( | ||
"beforeMessage" | ||
) < 2 | ||
) { | ||
overrideProcessRequest(hardhatWaffleProvider, estimateGasResult); | ||
} | ||
}; | ||
} | ||
|
||
function overrideProcessRequest(provider: any, estimateGasResult: BigNumber) { | ||
const curProcessRequest = | ||
provider._hardhatNetwork.provider._wrapped._wrapped._wrapped._ethModule | ||
.processRequest; | ||
|
||
if (curProcessRequest !== processRequest) { | ||
const originalProcess = | ||
provider._hardhatNetwork.provider._wrapped._wrapped._wrapped._ethModule.processRequest.bind( | ||
provider._hardhatNetwork.provider._wrapped._wrapped._wrapped._ethModule | ||
); | ||
provider._hardhatNetwork.provider._wrapped._wrapped._wrapped._ethModule.processRequest = | ||
(method: string, params: any[]) => { | ||
if (method === "eth_estimateGas") { | ||
return estimateGasResult.toHexString(); | ||
} else { | ||
return originalProcess(method, params); | ||
} | ||
}; | ||
|
||
processRequest = | ||
provider._hardhatNetwork.provider._wrapped._wrapped._wrapped._ethModule | ||
.processRequest; | ||
} | ||
} | ||
|
||
function getHardhatVMEventEmitter(provider: any) { | ||
const vm = | ||
provider?._hardhatNetwork.provider?._wrapped._wrapped?._wrapped?._node | ||
?._vmTracer?._vm; | ||
|
||
/** | ||
* There were changes related to the location of event emitter introduced | ||
* in Hardhat version 2.11.0. | ||
*/ | ||
return vm?.evm?.events ?? vm; | ||
} |
Oops, something went wrong.