Skip to content

Commit

Permalink
Merge pull request #186 from chugsplash/develop
Browse files Browse the repository at this point in the history
Plugins updates
  • Loading branch information
sam-goldman authored Nov 12, 2022
2 parents a7dde30 + c9feef4 commit de405ea
Show file tree
Hide file tree
Showing 17 changed files with 626 additions and 666 deletions.
5 changes: 5 additions & 0 deletions .changeset/good-maps-run.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@chugsplash/plugins': patch
---

Refactor remote bundling logic
5 changes: 5 additions & 0 deletions .changeset/grumpy-apricots-sneeze.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@chugsplash/contracts': patch
---

Hard-code build info file as a temporary fix
6 changes: 6 additions & 0 deletions .changeset/honest-shrimps-bake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@chugsplash/executor': patch
'@chugsplash/plugins': patch
---

Integrate etherscan verification into executor
5 changes: 5 additions & 0 deletions .changeset/loud-foxes-wash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@chugsplash/plugins': patch
---

Remove spinner from subtasks. Also update chugsplash-propose task to be more descriptive and robust.
6 changes: 6 additions & 0 deletions .changeset/silent-deers-know.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@chugsplash/core': patch
'@chugsplash/plugins': patch
---

Update chugsplash-register task to work locally
11 changes: 1 addition & 10 deletions packages/contracts/src/ifaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,7 @@ export const ProxyUpdaterArtifact = require('../artifacts/contracts/ProxyUpdater
export const DefaultAdapterArtifact = require('../artifacts/contracts/adapters/DefaultAdapter.sol/DefaultAdapter.json')
export const ProxyArtifact = require('../artifacts/contracts/libraries/Proxy.sol/Proxy.json')

const buildInfoFolderPath = path.join(
'..',
'contracts',
'artifacts',
'build-info'
)
const buildInfoFilePath = fs
.readdirSync(buildInfoFolderPath)
.map((file) => path.join(buildInfoFolderPath, file))[0]
export const buildInfo = JSON.parse(fs.readFileSync(buildInfoFilePath, 'utf8'))
export const buildInfo = require('../artifacts/build-info/b00e1a42c4580623826aa11edd72371a.json')

export const ChugSplashRegistryABI = ChugSplashRegistryArtifact.abi
export const ChugSplashBootLoaderABI = ChugSplashBootLoaderArtifact.abi
Expand Down
26 changes: 11 additions & 15 deletions packages/core/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
ChugSplashRegistryABI,
ChugSplashManagerABI,
ChugSplashManagerProxyArtifact,
// CHUGSPLASH_REGISTRY_ADDRESS,
CHUGSPLASH_REGISTRY_PROXY_ADDRESS,
} from '@chugsplash/contracts'

Expand Down Expand Up @@ -69,14 +68,14 @@ export const writeDeploymentArtifact = (

export const getProxyAddress = (
projectName: string,
target: string
referenceName: string
): string => {
// const chugSplashManagerAddress = getChugSplashManagerAddress(projectName)
const chugSplashManagerAddress = getChugSplashManagerProxyAddress(projectName)

return utils.getCreate2Address(
chugSplashManagerAddress,
utils.keccak256(utils.toUtf8Bytes(target)),
utils.keccak256(utils.toUtf8Bytes(referenceName)),
utils.solidityKeccak256(
['bytes', 'bytes'],
[
Expand Down Expand Up @@ -143,30 +142,27 @@ export const getChugSplashManagerProxyAddress = (projectName: string) => {
* @param projectName Name of the created project.
* @param projectOwner Owner of the ChugSplashManager contract deployed by this call.
* @param signer Signer to execute the transaction.
* @returns True if the project was successfully created and false if the project was already registered.
* @returns True if the project was registered for the first time in this call, and false if the
* project was already registered by the caller.
*/
export const registerChugSplashProject = async (
projectName: string,
projectOwner: string,
signer: Signer
) => {
): Promise<boolean> => {
const ChugSplashRegistry = getChugSplashRegistry(signer)

if (
(await ChugSplashRegistry.projects(projectName)) === constants.AddressZero
) {
try {
const tx = await ChugSplashRegistry.register(projectName, projectOwner)
await tx.wait()
} catch (err) {
throw new Error(
'Failed to register project. Try again with another project name.'
)
}
await (await ChugSplashRegistry.register(projectName, projectOwner)).wait()
return true
} else {
const existingProjectOwner = await getProjectOwner(projectName, signer)
if (existingProjectOwner !== (await signer.getAddress())) {
throw new Error(`Project already registered by: ${existingProjectOwner}.`)
} else {
return false
}
}
}
Expand Down Expand Up @@ -204,8 +200,8 @@ export const getChugSplashManagerImplementationAddress =
return managerImplementationAddress
}

export const log = async (message: string, hide?: boolean) => {
export const ChugSplashLog = async (text: string, hide?: boolean) => {
if (!hide) {
console.log(message)
console.log(text)
}
}
6 changes: 1 addition & 5 deletions packages/demo/contracts/SimpleStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@ contract SimpleStorage {

// We must instantiate the immutable variables in the constructor so that
// Solidity doesn't throw an error.
constructor(
uint8 _number,
bool _stored,
address _otherStorage
) {
constructor(uint8 _number, bool _stored, address _otherStorage) {
number = _number;
stored = _stored;
otherStorage = _otherStorage;
Expand Down
1 change: 1 addition & 0 deletions packages/executor/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
dist/
.env
cache
8 changes: 6 additions & 2 deletions packages/executor/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import {
CHUGSPLASH_REGISTRY_PROXY_ADDRESS,
} from '@chugsplash/contracts'
import { ChugSplashBundleState } from '@chugsplash/core'
import { getChainId } from '@eth-optimism/core-utils'

import { compileRemoteBundle } from './utils'
import { compileRemoteBundle, verifyChugSplashConfig } from './utils'

type Options = {
network: string
Expand Down Expand Up @@ -112,11 +113,14 @@ export class ChugSplashExecutor extends BaseServiceV2<Options, Metrics, State> {
chugSplashManager: manager,
bundleState,
bundle,
deployerAddress: await signer.getAddress(),
parsedConfig: canonicalConfig,
deployer: signer,
hide: false,
})

if ((await getChainId(this.state.wallet.provider)) !== 31337) {
await verifyChugSplashConfig(hre, proposalEvent.args.configUri)
}
}
}
}
Expand Down
101 changes: 9 additions & 92 deletions packages/executor/src/utils/compile.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import * as dotenv from 'dotenv'
import { SolcBuild } from 'hardhat/types'
import {
TASK_COMPILE_SOLIDITY_GET_SOLC_BUILD,
TASK_COMPILE_SOLIDITY_RUN_SOLCJS,
TASK_COMPILE_SOLIDITY_RUN_SOLC,
} from 'hardhat/builtin-tasks/task-names'
import { add0x } from '@eth-optimism/core-utils'
import {
CanonicalChugSplashConfig,
ChugSplashActionBundle,
} from '@chugsplash/core'
import { create } from 'ipfs-http-client'
import { ContractArtifact } from '@chugsplash/plugins'
import {
TASK_CHUGSPLASH_FETCH,
TASK_CHUGSPLASH_BUNDLE_REMOTE,
} from '@chugsplash/plugins'

// Load environment variables from .env
dotenv.config()
Expand All @@ -30,89 +25,11 @@ export const compileRemoteBundle = async (
bundle: ChugSplashActionBundle
canonicalConfig: CanonicalChugSplashConfig
}> => {
const canonicalConfig = await fetchChugSplashConfig(configUri)
const bundle = await hre.run('chugsplash-bundle-remote', {
deployConfig: canonicalConfig,
const canonicalConfig = await hre.run(TASK_CHUGSPLASH_FETCH, {
configUri,
})
return { bundle, canonicalConfig }
}

export const getArtifactsFromCanonicalConfig = async (
hre: any,
canonicalConfig: CanonicalChugSplashConfig
): Promise<{
[contractName: string]: ContractArtifact
}> => {
const artifacts = {}
for (const source of canonicalConfig.inputs) {
const solcBuild: SolcBuild = await hre.run(
TASK_COMPILE_SOLIDITY_GET_SOLC_BUILD,
{
quiet: true,
solcVersion: source.solcVersion,
}
)

let output: any // TODO: Compiler output
if (solcBuild.isSolcJs) {
output = await hre.run(TASK_COMPILE_SOLIDITY_RUN_SOLCJS, {
input: source.input,
solcJsPath: solcBuild.compilerPath,
})
} else {
output = await hre.run(TASK_COMPILE_SOLIDITY_RUN_SOLC, {
input: source.input,
solcPath: solcBuild.compilerPath,
})
}

for (const [sourceName, fileOutput] of Object.entries(output.contracts)) {
for (const [contractName, contractOutput] of Object.entries(fileOutput)) {
artifacts[contractName] = {
bytecode: add0x(contractOutput.evm.bytecode.object),
storageLayout: contractOutput.storageLayout,
contractName,
sourceName,
abi: contractOutput.abi,
sources: output.sources,
immutableReferences:
output.contracts[sourceName][contractName].evm.deployedBytecode
.immutableReferences,
}
}
}
}
return artifacts
}

// TODO: change file name or add another file
export const fetchChugSplashConfig = async (
configUri: string
): Promise<CanonicalChugSplashConfig> => {
const projectCredentials = `${process.env.IPFS_PROJECT_ID}:${process.env.IPFS_API_KEY_SECRET}`
const ipfs = create({
host: 'ipfs.infura.io',
port: 5001,
protocol: 'https',
headers: {
authorization: `Basic ${Buffer.from(projectCredentials).toString(
'base64'
)}`,
},
const bundle = await hre.run(TASK_CHUGSPLASH_BUNDLE_REMOTE, {
canonicalConfig,
})

let config: CanonicalChugSplashConfig
if (configUri.startsWith('ipfs://')) {
const decoder = new TextDecoder()
let data = ''
const stream = await ipfs.cat(configUri.replace('ipfs://', ''))
for await (const chunk of stream) {
// Chunks of data are returned as a Uint8Array. Convert it back to a string
data += decoder.decode(chunk, { stream: true })
}
config = JSON.parse(data)
} else {
throw new Error('unsupported URI type')
}
return config
return { bundle, canonicalConfig }
}
52 changes: 32 additions & 20 deletions packages/executor/src/utils/etherscan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@ import assert from 'assert'

import { Contract } from 'ethers'
import {
CanonicalChugSplashConfig,
CompilerInput,
getChugSplashManagerProxyAddress,
getProxyAddress,
parseChugSplashConfig,
} from '@chugsplash/core'
import { getConstructorArgs } from '@chugsplash/plugins'
import {
getConstructorArgs,
TASK_CHUGSPLASH_FETCH,
getArtifactsFromParsedCanonicalConfig,
} from '@chugsplash/plugins'
import { TASK_VERIFY_GET_ETHERSCAN_ENDPOINT } from '@nomiclabs/hardhat-etherscan/dist/src/constants'
import { EtherscanURLs } from '@nomiclabs/hardhat-etherscan/dist/src/types'
import {
Expand All @@ -28,11 +35,6 @@ import { ChugSplashManagerABI } from '@chugsplash/contracts'
import { EthereumProvider } from 'hardhat/types'
import { request } from 'undici'

import {
fetchChugSplashConfig,
getArtifactsFromCanonicalConfig,
} from './compile'

export interface EtherscanResponseBody {
status: string
message: string
Expand All @@ -44,30 +46,32 @@ export const RESPONSE_OK = '1'
export const verifyChugSplashConfig = async (hre: any, configUri: string) => {
const { etherscanApiKey, etherscanApiEndpoints } = await getEtherscanInfo(hre)

const canonicalConfig = await fetchChugSplashConfig(configUri)
const artifacts = await getArtifactsFromCanonicalConfig(hre, canonicalConfig)

const canonicalConfig = await hre.run(TASK_CHUGSPLASH_FETCH, {
configUri,
})
const artifacts = await getArtifactsFromParsedCanonicalConfig(
hre,
parseChugSplashConfig(canonicalConfig) as CanonicalChugSplashConfig
)
const ChugSplashManager = new Contract(
getChugSplashManagerProxyAddress(canonicalConfig.options.projectName),
ChugSplashManagerABI,
hre.ethers.provider
)

for (const [referenceName, contractConfig] of Object.entries(
canonicalConfig.contracts
)) {
const artifact = artifacts[contractConfig.contract]
const { abi, contractName, sourceName, sources, immutableReferences } =
artifact
const { constructorArgValues } = await getConstructorArgs(
for (const referenceName of Object.keys(canonicalConfig.contracts)) {
const artifact = artifacts[referenceName]
const { abi, contractName, sourceName, compilerOutput } = artifact
const { constructorArgValues } = getConstructorArgs(
canonicalConfig,
referenceName,
abi,
sources,
immutableReferences
compilerOutput,
sourceName,
contractName
)

const contractAddress = await ChugSplashManager.implementations(
const implementationAddress = await ChugSplashManager.implementations(
referenceName
)

Expand All @@ -79,7 +83,7 @@ export const verifyChugSplashConfig = async (hre: any, configUri: string) => {
hre.network.name,
hre.network.provider,
etherscanApiEndpoints,
contractAddress,
implementationAddress,
sourceName,
contractName,
abi,
Expand All @@ -88,6 +92,14 @@ export const verifyChugSplashConfig = async (hre: any, configUri: string) => {
compilerInput.solcVersion,
constructorArgValues
)

await linkProxyWithImplementation(
etherscanApiEndpoints,
etherscanApiKey,
getProxyAddress(canonicalConfig.options.projectName, referenceName),
implementationAddress,
contractName
)
}
}

Expand Down
Loading

0 comments on commit de405ea

Please sign in to comment.