Skip to content

Commit

Permalink
feat(scratch deploy): count total gas used
Browse files Browse the repository at this point in the history
  • Loading branch information
arwer13 committed Oct 29, 2023
1 parent 1f2b68a commit e9071f5
Show file tree
Hide file tree
Showing 21 changed files with 151 additions and 91 deletions.
2 changes: 1 addition & 1 deletion docs/scratch-deploy.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ yarn hardhat node

To do Holešky deployment, the following parameters must be set up via env variables:

- `DEPLOYER`. The deployer address. The deployer must own its private key. It must have enough ether.
- `DEPLOYER`. The deployer address. The deployer must own its private key. To ensure proper operation, it should have an adequate amount of ether. The total deployment gas cost is approximately 100,000,000 gas, and this cost can vary based on whether specific components of the environment, such as the DepositContract, are deployed or not.
- `RPC_URL`. Address of of the Ethereum RPC node to use. E.g. for Infura it is `https://holesky.infura.io/v3/<yourProjectId>`
- `GAS_PRIORITY_FEE`. Gas priority fee. By default set to `2`
- `GAS_MAX_FEE`. Gas max fee. By default set to `100`
Expand Down
64 changes: 51 additions & 13 deletions scripts/helpers/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,42 @@ const fs = require('fs').promises
const chalk = require('chalk')
const { assert } = require('chai')

const { log, logDeploy, logDeployTxData } = require('./log')
const { log, logDeploy, logDeployTxData, OK } = require('./log')
const { getTxData } = require('./tx-data')


const GAS_PRICE = process.env.GAS_PRICE || null
const GAS_PRIORITY_FEE = process.env.GAS_PRIORITY_FEE || null
const GAS_MAX_FEE = process.env.GAS_MAX_FEE || null

let TOTAL_GAS_USED = 0

function getTotalGasUsed() {
return TOTAL_GAS_USED
class TotalGasCounterPrivate {
constructor() {
this.totalGasUsed = 0
}
}
class TotalGasCounter {
constructor() {
throw new Error('Use TotalGasCounter.getInstance()');
}
static getInstance() {
if (!TotalGasCounter.instance) {
TotalGasCounter.instance = new TotalGasCounterPrivate()
}
return TotalGasCounter.instance
}
static add(gasUsed) {
return this.getInstance().totalGasUsed += gasUsed
}
static getTotalGasUsed() {
return this.getInstance().totalGasUsed
}
static async incrementTotalGasUsedInStateFile() {
const netId = await web3.eth.net.getId()
const state = readNetworkState(network.name, netId)
state.initialDeployTotalGasUsed += TotalGasCounter.getTotalGasUsed()
persistNetworkState(network.name, netId, state)
}
}

async function getDeploymentGasUsed(contract) {
Expand Down Expand Up @@ -50,6 +74,19 @@ async function getDeployTx(artifactName, opts = {}) {
return await getTxData(txObj)
}

async function makeTx(contract, funcName, args, txParams) {
console.log(`${contract.constructor._json.contractName}[${contract.address}].${funcName}()...`)
const receipt = await contract[funcName](...args, txParams)
const gasUsed = receipt.gasUsed ? receipt.gasUsed : receipt.receipt.gasUsed
if (gasUsed === undefined) {
console.log({ receipt })
assert(false)
}
console.log(`${OK} tx: ${receipt.tx} (gasUsed ${gasUsed})`)
TotalGasCounter.add(gasUsed)
return receipt
}

async function deploy(artifactName, artifacts, deploy) {
const Artifact = artifacts.require(artifactName)
return await logDeploy(artifactName, deploy ? deploy(Artifact) : Artifact.new())
Expand Down Expand Up @@ -202,7 +239,7 @@ async function deployWithoutProxy(nameInState, artifactName, deployer, construct

const gasUsed = await getDeploymentGasUsed(contract)
console.log(`done: ${contract.address} (gas used ${gasUsed})`)
TOTAL_GAS_USED += gasUsed
TotalGasCounter.add(gasUsed)

state[nameInState] = {
...state[nameInState],
Expand All @@ -222,10 +259,8 @@ async function deployImplementation(nameInState, artifactName, deployer, constru

process.stdout.write(`Deploying implementation for proxy of ${artifactName}... `)
const contract = await deployContract(artifactName, constructorArgs, deployer)

const gasUsed = await getDeploymentGasUsed(contract)
TOTAL_GAS_USED += gasUsed

TotalGasCounter.add(gasUsed)
console.log(`done: ${contract.address} (gas used ${gasUsed})`)

state[nameInState] = { ...state[nameInState] }
Expand All @@ -246,12 +281,12 @@ async function deployBehindOssifiableProxy(nameInState, artifactName, proxyOwner
if (implementation === null) {
process.stdout.write(`Deploying implementation for proxy of ${artifactName}... `)
const contract = await deployContract(artifactName, constructorArgs, deployer)

const gasUsed = await getDeploymentGasUsed(contract)
TOTAL_GAS_USED += gasUsed
TotalGasCounter.add(gasUsed)
implementation = contract.address

console.log(`done: ${implementation} (gas used ${gasUsed})`)

} else {
console.log(`Using pre-deployed implementation of ${artifactName}: ${implementation}`)
}
Expand All @@ -260,7 +295,7 @@ async function deployBehindOssifiableProxy(nameInState, artifactName, proxyOwner
const proxyConstructorArgs = [implementation, proxyOwner, '0x']
const proxy = await deployContract(proxyContractName, proxyConstructorArgs, deployer)
const gasUsed = await getDeploymentGasUsed(proxy)
TOTAL_GAS_USED += gasUsed
TotalGasCounter.add(gasUsed)
console.log(`done: ${proxy.address} (gas used ${gasUsed})`)

state[nameInState] = { ...state[nameInState] }
Expand All @@ -287,8 +322,10 @@ async function updateProxyImplementation(nameInState, artifactName, proxyAddress
const proxy = await artifacts.require('OssifiableProxy').at(proxyAddress)

const implementation = await deployContract(artifactName, constructorArgs, proxyOwner)
const gasUsed = await getDeploymentGasUsed(implementation)
TotalGasCounter.add(gasUsed)

await log.makeTx(proxy, 'proxy__upgradeTo', [implementation.address], { from: proxyOwner })
await makeTx(proxy, 'proxy__upgradeTo', [implementation.address], { from: proxyOwner })

state[nameInState] = { ...state[nameInState] }
state[nameInState].implementation = {
Expand Down Expand Up @@ -318,6 +355,7 @@ module.exports = {
deployImplementation,
deployBehindOssifiableProxy,
updateProxyImplementation,
getTotalGasUsed,
getContractPath,
makeTx,
TotalGasCounter,
}
9 changes: 0 additions & 9 deletions scripts/helpers/log.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,7 @@ async function logTx(desc, promise) {
return result
}

async function txWithLog(contract, funcName, args, txParams) {
console.log(`${contract.constructor._json.contractName}[${contract.address}].${funcName}()...`)
const receipt = await contract[funcName](...args, txParams)
console.log(`${OK} tx: ${receipt.tx}`)
return receipt
}

log.tx = logTx
log.makeTx = txWithLog

async function logDeployTxData(contractName, txData) {
logSplitter(`To deploy ${yl(contractName)}, send the following transaction:`)
Expand All @@ -127,7 +119,6 @@ module.exports = {
logDeploy,
logDeployTxData,
logTx,
txWithLog,
rd,
yl,
gr,
Expand Down
6 changes: 4 additions & 2 deletions scripts/scratch/01-deploy-lido-template-and-bases.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const chalk = require('chalk')

const runOrWrapScript = require('../helpers/run-or-wrap-script')
const { log, yl, gr } = require('../helpers/log')
const { deployImplementation, deployWithoutProxy } = require('../helpers/deploy')
const { log } = require('../helpers/log')
const { deployImplementation, deployWithoutProxy, TotalGasCounter } = require('../helpers/deploy')
const { readNetworkState, assertRequiredNetworkState, persistNetworkState } = require('../helpers/persisted-network-state')
const { APP_NAMES } = require('../constants')

Expand Down Expand Up @@ -51,6 +51,8 @@ async function deployTemplate({ web3, artifacts }) {
})

log.splitter()

await TotalGasCounter.incrementTotalGasUsedInStateFile()
}

module.exports = runOrWrapScript(deployTemplate, module)
7 changes: 3 additions & 4 deletions scripts/scratch/02-obtain-deployed-instances.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
const chalk = require('chalk')

const runOrWrapScript = require('../helpers/run-or-wrap-script')
const { log, logSplitter, logWideSplitter, logHeader, logTx } = require('../helpers/log')
const { useOrGetDeployed, assertDeployedBytecode, getTxBlock } = require('../helpers/deploy')
const { log, logWideSplitter, logHeader } = require('../helpers/log')
const { assertDeployedBytecode } = require('../helpers/deploy')
const { assert } = require('../helpers/assert')
const { readNetworkState, persistNetworkState, assertRequiredNetworkState } = require('../helpers/persisted-network-state')
const { readNetworkState, assertRequiredNetworkState } = require('../helpers/persisted-network-state')

const { APP_NAMES } = require('../constants')
const { network } = require('hardhat')
Expand Down
13 changes: 8 additions & 5 deletions scripts/scratch/03-register-ens-domain.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ const keccak256 = require('js-sha3').keccak_256
const runOrWrapScript = require('../helpers/run-or-wrap-script')
const { assert } = require('../helpers/assert')
const { log, yl, gr } = require('../helpers/log')
const { readNetworkState, assertRequiredNetworkState, persistNetworkState } = require('../helpers/persisted-network-state')
const { makeTx, TotalGasCounter } = require('../helpers/deploy')
const { readNetworkState, assertRequiredNetworkState } = require('../helpers/persisted-network-state')

const TLD = 'eth'
const CONTROLLER_INTERFACE_ID = '0x018fac06'
Expand Down Expand Up @@ -100,9 +101,9 @@ async function deployTemplate({ web3, artifacts }) {

log.splitter()

await log.makeTx(controller, 'commit', [commitment], { from: state.deployer })
await makeTx(controller, 'commit', [commitment], { from: state.deployer })

await log.makeTx(controller, 'register', [domainLabel, domainOwner, domainRegDuration, salt], {
await makeTx(controller, 'register', [domainLabel, domainOwner, domainRegDuration, salt], {
from: state.deployer,
value: '0x' + registerTxValue.toString(16),
})
Expand All @@ -112,14 +113,16 @@ async function deployTemplate({ web3, artifacts }) {
log(`ENS domain new owner:`, yl(domainOwner))
if ((await ens.owner(node)) === state.deployer) {
log(`Transferring name ownership from owner ${chalk.yellow(state.deployer)} to template ${chalk.yellow(domainOwner)}`)
await log.makeTx(ens, 'setOwner', [node, domainOwner], { from: state.deployer })
await makeTx(ens, 'setOwner', [node, domainOwner], { from: state.deployer })
} else {
log(`Creating the subdomain and assigning it to template ${chalk.yellow(domainOwner)}`)
await log.makeTx(ens, 'setSubnodeOwner', [tldNode, labelHash, domainOwner], { from: state.deployer })
await makeTx(ens, 'setSubnodeOwner', [tldNode, labelHash, domainOwner], { from: state.deployer })
}

log.splitter()
}

await TotalGasCounter.incrementTotalGasUsedInStateFile()
}

const HOUR = 60 * 60
Expand Down
5 changes: 4 additions & 1 deletion scripts/scratch/05-deploy-apm.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const { log, logSplitter, logWideSplitter } = require('../helpers/log')
const { assertNoEvents } = require('../helpers/events')
const { readNetworkState, assertRequiredNetworkState, persistNetworkState } = require('../helpers/persisted-network-state')
const { getENSNodeOwner } = require('../components/ens')
const { makeTx, TotalGasCounter } = require('../helpers/deploy')

const REQUIRED_NET_STATE = [
'deployer',
Expand Down Expand Up @@ -59,14 +60,16 @@ async function deployAPM({ web3, artifacts }) {
const from = state.deployer

const lidoApmDeployArguments = [parentHash, subHash]
const receipt = await log.makeTx(template, 'deployLidoAPM', lidoApmDeployArguments, { from })
const receipt = await makeTx(template, 'deployLidoAPM', lidoApmDeployArguments, { from })

state.lidoApm = {
...state.lidoApm,
deployArguments: lidoApmDeployArguments,
deployTx: receipt.tx,
}
persistNetworkState(network.name, netId, state)

await TotalGasCounter.incrementTotalGasUsedInStateFile()
}

function splitDomain(domain) {
Expand Down
7 changes: 5 additions & 2 deletions scripts/scratch/07-create-app-repos.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const runOrWrapScript = require('../helpers/run-or-wrap-script')
const { log, logSplitter, logWideSplitter } = require('../helpers/log')
const { assertLastEvent } = require('../helpers/events')
const { readNetworkState, assertRequiredNetworkState, persistNetworkState } = require('../helpers/persisted-network-state')
const { makeTx, TotalGasCounter } = require('../helpers/deploy')

const { APP_NAMES } = require('../constants')

Expand Down Expand Up @@ -63,7 +64,7 @@ async function createAppRepos({ web3, artifacts }) {

console.log({arguments, from})

const lidoAppsReceipt = await log.makeTx(template, 'createRepos', createReposArguments, { from })
const lidoAppsReceipt = await makeTx(template, 'createRepos', createReposArguments, { from })
console.log(`=== Aragon Lido Apps Repos (Lido, AccountingOracle, NodeOperatorsRegistry deployed: ${lidoAppsReceipt.tx} ===`)

const createStdAragonReposArguments = [
Expand All @@ -73,12 +74,14 @@ async function createAppRepos({ web3, artifacts }) {
state['app:aragon-voting'].implementation.address,
]

const aragonStdAppsReceipt = await log.makeTx(template, 'createStdAragonRepos', createStdAragonReposArguments, { from })
const aragonStdAppsReceipt = await makeTx(template, 'createStdAragonRepos', createStdAragonReposArguments, { from })
console.log(`=== Aragon Std Apps Repos (Agent, Finance, TokenManager, Voting deployed: ${aragonStdAppsReceipt.tx} ===`)
state.lidoTemplateCreateStdAppReposTx = aragonStdAppsReceipt.tx

logSplitter()
persistNetworkState(network.name, netId, state)

await TotalGasCounter.incrementTotalGasUsedInStateFile()
}

module.exports = runOrWrapScript(createAppRepos, module)
6 changes: 4 additions & 2 deletions scripts/scratch/08-deploy-dao.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const chalk = require('chalk')
const { assert } = require('chai')
const { getEvents } = require('@aragon/contract-helpers-test')
const { hash: namehash } = require('eth-ens-namehash')
const { toChecksumAddress } = require('web3-utils')
const { makeTx, TotalGasCounter } = require('../helpers/deploy')

const runOrWrapScript = require('../helpers/run-or-wrap-script')
const { log } = require('../helpers/log')
Expand Down Expand Up @@ -64,13 +64,15 @@ async function deployDAO({ web3, artifacts }) {

log(`Using DAO token settings:`, daoInitialSettings.token)
log(`Using DAO voting settings:`, daoInitialSettings.voting)
const receipt = await log.makeTx(template, 'newDAO', [
const receipt = await makeTx(template, 'newDAO', [
daoInitialSettings.token.name,
daoInitialSettings.token.symbol,
votingSettings,
], { from: state.deployer })
state.lidoTemplateNewDaoTx = receipt.tx
persistNetworkState(network.name, netId, state)

await TotalGasCounter.incrementTotalGasUsedInStateFile()
}

async function checkAppRepos(state) {
Expand Down
12 changes: 5 additions & 7 deletions scripts/scratch/10-issue-tokens.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
const BN = require('bn.js')
const path = require('path')
const chalk = require('chalk')
const { assert } = require('chai')
const { getEvents } = require('@aragon/contract-helpers-test')
const { hash: namehash } = require('eth-ens-namehash')
const { toChecksumAddress } = require('web3-utils')
const { makeTx, TotalGasCounter } = require('../helpers/deploy')

const runOrWrapScript = require('../helpers/run-or-wrap-script')
const { log } = require('../helpers/log')
const { assertLastEvent } = require('../helpers/events')
const { readNetworkState, persistNetworkState, assertRequiredNetworkState } = require('../helpers/persisted-network-state')
const { readNetworkState, assertRequiredNetworkState } = require('../helpers/persisted-network-state')

const { APP_NAMES } = require('../constants')
const VALID_APP_NAMES = Object.entries(APP_NAMES).map((e) => e[1])
Expand Down Expand Up @@ -76,11 +72,13 @@ async function issueTokens({ web3, artifacts }) {

endTotalSupply.iadd(bigSum(iAmounts))

await log.makeTx(template, 'issueTokens',
await makeTx(template, 'issueTokens',
[iHolders, iAmounts, vesting.start, vesting.cliff, vesting.end, vesting.revokable, '0x' + endTotalSupply.toString(16)]
, { from: state.deployer },
)
}

await TotalGasCounter.incrementTotalGasUsedInStateFile()
}

function bigSum(amounts, initialAmount = 0) {
Expand Down
6 changes: 4 additions & 2 deletions scripts/scratch/11-finalize-dao.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const runOrWrapScript = require('../helpers/run-or-wrap-script')
const { log } = require('../helpers/log')
const { readNetworkState, assertRequiredNetworkState } = require('../helpers/persisted-network-state')
const { assertLastEvent } = require('../helpers/events')
const { makeTx, TotalGasCounter } = require('../helpers/deploy')

const { APP_NAMES } = require('../constants')
const { assertVesting } = require('./checks/dao-token')
Expand Down Expand Up @@ -62,14 +63,15 @@ async function finalizeDAO({ web3, artifacts }) {
unvestedTokensAmount: '0' // since we're minting them during the finalizeDAO call below
}
})

log.splitter()

await log.makeTx(template, 'finalizeDAO', [
await makeTx(template, 'finalizeDAO', [
state.daoAragonId,
state.vestingParams.unvestedTokensAmount,
state.stakingRouter.proxy.address
], { from: state.deployer })

await TotalGasCounter.incrementTotalGasUsedInStateFile()
}

module.exports = runOrWrapScript(finalizeDAO, module)
Loading

0 comments on commit e9071f5

Please sign in to comment.