Skip to content

Commit

Permalink
Merge pull request #323 from alephium/improve-deploy-to-devnet
Browse files Browse the repository at this point in the history
Improve the return type of deployToDevnet
  • Loading branch information
polarker authored Feb 29, 2024
2 parents 039a4a5 + ed0090e commit 2bf4ce4
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 20 deletions.
29 changes: 18 additions & 11 deletions packages/cli/src/codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import * as prettier from 'prettier'
import path from 'path'
import fs from 'fs'
import { Configuration, DEFAULT_CONFIGURATION_VALUES } from './types'
import { getDeploymentFilePath } from './utils'
import { getDeploymentFilePath, taskIdToVariable } from './utils'
import { Deployments, DeploymentsPerAddress } from './deployment'

const header = `/* Autogenerated file. Do not edit manually. */\n/* tslint:disable */\n/* eslint-disable */\n\n`
Expand Down Expand Up @@ -543,7 +543,7 @@ function genToDeployments(contracts: string[], optionalContracts: string[], allS
const contractInstances = contracts.map((taskId) => {
const typeName = getTypeFromTaskId(taskId)
return `
${convertToVariableName(taskId)}: {
${taskIdToVariable(taskId)}: {
...json.contracts['${taskId}'],
contractInstance: ${typeName}.at(json.contracts['${taskId}'].contractInstance.address)
}
Expand All @@ -552,13 +552,13 @@ function genToDeployments(contracts: string[], optionalContracts: string[], allS
const optionalContractInstances = optionalContracts.map((taskId) => {
const typeName = getTypeFromTaskId(taskId)
return `
${convertToVariableName(taskId)}: json.contracts['${taskId}'] === undefined ? undefined : {
${taskIdToVariable(taskId)}: json.contracts['${taskId}'] === undefined ? undefined : {
...json.contracts['${taskId}'],
contractInstance: ${typeName}.at(json.contracts['${taskId}'].contractInstance.address)
}
`
})
const scripts = allScripts.map((taskId) => `${convertToVariableName(taskId)}: json.scripts['${taskId}']`).join(',')
const scripts = allScripts.map((taskId) => `${taskIdToVariable(taskId)}: json.scripts['${taskId}']`).join(',')
const allContractInstances = contractInstances.concat(optionalContractInstances).join(',')
return `
function toDeployments(json: any): Deployments {
Expand All @@ -572,18 +572,14 @@ function genToDeployments(contracts: string[], optionalContracts: string[], allS
`
}

function convertToVariableName(taskId: string): string {
return taskId.replace(/[:\-]/g, '_')
}

function genContractField(taskId: string, optional: boolean): string {
const typeName = getTypeFromTaskId(taskId)
const varName = convertToVariableName(taskId)
const varName = taskIdToVariable(taskId)
return `${varName}${optional ? '?' : ''}: DeployContractExecutionResult<${typeName}Instance>`
}

function genScriptField(taskId: string, optional: boolean): string {
const varName = convertToVariableName(taskId)
const varName = taskIdToVariable(taskId)
return `${varName}${optional ? '?' : ''}: RunScriptResult`
}

Expand Down Expand Up @@ -686,11 +682,22 @@ export function sortByName<T extends { artifact: { name: string } }>(artifacts:
return artifacts.sort((a, b) => (a.artifact.name > b.artifact.name ? 1 : -1))
}

function cleanCode(outDir: string) {
const files = fs.readdirSync(outDir)
files.forEach((file) => {
const filePath = path.join(outDir, file)
const filename = path.basename(file)
if (filename !== 'deployments.ts') {
fs.unlinkSync(filePath)
}
})
}

export function codegen(artifactDir: string) {
const outDirTemp = path.join(artifactDir, 'ts')
const outDir = path.isAbsolute(outDirTemp) ? outDirTemp : path.resolve(outDirTemp)
if (fs.existsSync(outDir)) {
fs.rmSync(outDir, { recursive: true, force: true })
cleanCode(outDir)
}
fs.mkdirSync(outDir, { recursive: true })

Expand Down
35 changes: 34 additions & 1 deletion packages/cli/src/deployment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.

import { PrivateKeyWallet } from '@alephium/web3-wallet'
import { Deployments, DeploymentsPerAddress, recordEqual, validatePrivateKeys } from './deployment'
import { web3 } from '@alephium/web3'
import { ContractInstance, web3 } from '@alephium/web3'
import { randomContractAddress, testAddress } from '@alephium/web3-test'
import { DeployContractExecutionResult } from './types'

describe('deployments', () => {
it('test record equal', () => {
Expand Down Expand Up @@ -85,4 +87,35 @@ describe('deployments', () => {
expect(() => validatePrivateKeys(keys.join(','))).toThrowError(`Duplicated private keys on group ${size - 1}`)
})
})

it('should get contract instance from deployments', () => {
class FakeContractInstance extends ContractInstance {}
function fake(): DeployContractExecutionResult {
return {
contractInstance: new FakeContractInstance(randomContractAddress()),
txId: '',
unsignedTx: '',
signature: '',
gasAmount: 0,
gasPrice: '',
blockHash: '',
codeHash: ''
}
}

const contracts = new Map<string, DeployContractExecutionResult>()
contracts.set('Foo', fake())
contracts.set('Bar', fake())
contracts.set('Baz_1', fake())
const deployments = new Deployments([new DeploymentsPerAddress(testAddress, contracts, new Map(), new Map())])

expect(deployments['tryGetDeployedContract']('Foo')).toEqual(contracts.get('Foo')!)
expect(deployments['tryGetDeployedContract']('Bar')).toEqual(contracts.get('Bar')!)
expect(deployments['tryGetDeployedContract']('Foo', 1)).toEqual(undefined)
expect(deployments['tryGetDeployedContract']('Bar', 1)).toEqual(undefined)
expect(deployments['tryGetDeployedContract']('Baz')).toEqual(undefined)
expect(deployments['tryGetDeployedContract']('Foo', undefined, 'Foo:1')).toEqual(undefined)
expect(deployments['tryGetDeployedContract']('Baz', undefined, 'Baz:1')).toEqual(contracts.get('Baz_1'))
expect(deployments['tryGetDeployedContract']('Baz', undefined, 'Baz:2')).toEqual(undefined)
})
})
27 changes: 27 additions & 0 deletions packages/cli/src/deployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import {
getNetwork,
loadConfig,
retryFetch,
taskIdToVariable,
waitTxConfirmed,
waitUserConfirmation
} from './utils'
Expand Down Expand Up @@ -157,6 +158,32 @@ export class Deployments {
const deploymentsFile = getDeploymentFilePath(configuration, networkId)
return Deployments.from(deploymentsFile)
}

private tryGetDeployedContract(
contractName: string,
group?: number,
taskId?: string
): DeployContractExecutionResult | undefined {
const deployments = group !== undefined ? this.deploymentsByGroup(group) : this.deployments[0]
if (deployments === undefined) {
return undefined
}
return taskId === undefined
? deployments.contracts.get(`${contractName}`)
: deployments.contracts.get(`${taskIdToVariable(taskId)}`)
}

getInstance<I extends ContractInstance>(
contract: ContractFactory<I, any>,
group?: number,
taskId?: string
): I | undefined {
const result = this.tryGetDeployedContract(contract.contract.name, group, taskId)
if (result === undefined) {
return undefined
}
return contract.at(result.contractInstance.address)
}
}

export async function getDeploymentResult(filepath: string): Promise<DeploymentsPerAddress> {
Expand Down
4 changes: 4 additions & 0 deletions packages/cli/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,7 @@ export function waitUserConfirmation(msg: string): Promise<boolean> {
})
})
}

export function taskIdToVariable(taskId: string): string {
return taskId.replace(/[:\-]/g, '_')
}
13 changes: 5 additions & 8 deletions packages/cli/templates/base/test/token.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { web3, Project, TestContractParams, addressFromContractId, AssetOutput, DUST_AMOUNT } from '@alephium/web3'
import { web3, Project, TestContractParams, addressFromContractId, AssetOutput, DUST_AMOUNT, groupOfAddress } from '@alephium/web3'
import { expectAssertionError, randomContractId, testAddress, testNodeWallet } from '@alephium/web3-test'
import { deployToDevnet } from '@alephium/cli'
import { TokenFaucet, TokenFaucetTypes, Withdraw } from '../artifacts/ts'
Expand Down Expand Up @@ -117,23 +117,20 @@ describe('integration tests', () => {
await signer.setSelectedAccount(testAddress)
const testGroup = account.group

const deployed = deployments.getDeployedContractResult(testGroup, 'TokenFaucet')
if (deployed === undefined) {
const faucet = deployments.getInstance(TokenFaucet, testGroup)
if (faucet === undefined) {
console.log(`The contract is not deployed on group ${account.group}`)
continue
}
const tokenId = deployed.contractInstance.contractId
const tokenAddress = deployed.contractInstance.address
expect(deployed.contractInstance.groupIndex).toEqual(testGroup)

const faucet = TokenFaucet.at(tokenAddress)
expect(faucet.groupIndex).toEqual(testGroup)
const initialState = await faucet.fetchState()
const initialBalance = initialState.fields.balance

// Call `withdraw` function 10 times
for (let i = 0; i < 10; i++) {
await Withdraw.execute(signer, {
initialFields: { token: tokenId, amount: 1n },
initialFields: { token: faucet.contractId, amount: 1n },
attoAlphAmount: DUST_AMOUNT * 2n
})

Expand Down

0 comments on commit 2bf4ce4

Please sign in to comment.