Skip to content

Commit

Permalink
feat!: specify and check contract descriptor file version
Browse files Browse the repository at this point in the history
BREAKING CHANGE: The format of contract descriptor file changed
Contract descriptors needs to be regenerated.
  • Loading branch information
davidyuk committed Apr 5, 2023
1 parent 2516446 commit ea17f80
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 6 deletions.
10 changes: 8 additions & 2 deletions src/actions/contract.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { initSdk, initSdkByWalletFile } from '../utils/cli';
import { print, printTransaction, printUnderscored } from '../utils/print';
import CliError from '../utils/CliError';

const DESCRIPTOR_VERSION = 0;
const resolve = (filename) => path.resolve(process.cwd(), filename);

async function getContractParams({
Expand All @@ -34,6 +35,9 @@ async function getContractParams({
let descriptor = {};
if (descrPath && (!descrMayNotExist || await fs.exists(resolve(descrPath)))) {
descriptor = await fs.readJson(resolve(descrPath));
if (descriptor.version !== DESCRIPTOR_VERSION) {
throw new CliError(`Unsupported contract descriptor: version ${descriptor.version}, supported ${DESCRIPTOR_VERSION}`);
}
}
if (contractSource) {
const contractSourcePath = resolve(contractSource);
Expand All @@ -44,11 +48,12 @@ async function getContractParams({
descriptor.fileSystem = utils.getFilesystem(contractSourcePath);
console.log = originalConsoleLog;
}
const { address, version, ...other } = descriptor;
return {
contractAddress: contractAddress ?? descriptor.address,
contractAddress: contractAddress ?? address,
// TODO: either remove calldata methods in cli or reconsider getContractInstance requirements
...dummySource && { source: 'invalid-source' },
...descriptor,
...other,
...contractBytecode && { bytecode: encode(await fs.readFile(resolve(contractBytecode)), 'cb') },
...contractAci && { aci: await fs.readJson(resolve(contractAci)) },
};
Expand Down Expand Up @@ -98,6 +103,7 @@ export async function deploy(walletPath, args, options) {
options.descrPath ||= path
.resolve(process.cwd(), `${filename}.deploy.${result.address.slice(3)}.json`);
const descriptor = {
version: DESCRIPTOR_VERSION,
address: result.address,
bytecode: contract.bytecode,
// eslint-disable-next-line no-underscore-dangle
Expand Down
44 changes: 40 additions & 4 deletions test/contract.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ describe('Contract Module', function contractTests() {

it('deploys contract with custom descrPath', async () => {
const descrPath = './not-existing/testDescriptor.json';
await executeContract([
const { address } = await executeContract([
'deploy',
WALLET_NAME, '--password', 'test',
'--contractSource', contractSourceFile,
Expand All @@ -107,9 +107,45 @@ describe('Contract Module', function contractTests() {
]);
expect(await fs.exists(descrPath)).to.be.equal(true);
const descriptor = await fs.readJson(descrPath);
expect(descriptor.address).to.satisfy((b) => b.startsWith('ct_'));
expect(descriptor.bytecode).to.satisfy((b) => b.startsWith('cb_'));
expect(descriptor.aci).to.an('object');
expect(descriptor).to.eql({
version: 0,
address,
bytecode: 'cb_+L5GA6DW8xFr9ZDBic0l5WTm/5EvGm6k52N0ZwO2agbcg2M00cC4kbhX/kTWRB8ANwEHNwAaBoIAAQM//pKLIDYANwIHBwcMAoIMAQICAxHQ4oJSDAEABAMR0OKCUv7Q4oJSAjcCBwcHFBQAAgD+6YyQGwA3AGcHBwEDLwICBAYItC8EEUTWRB8RaW5pdBGSiyA2EXRlc3QR0OKCUjEuVGVzdExpYi5zdW0R6YyQGxlnZXRNYXCCLwCFNi4xLjAAxRDrZA==',
aci: {
encodedAci: {
contract: {
functions: [{
arguments: [{ name: '_z', type: 'int' }],
name: 'init',
payable: false,
returns: 'Identity.state',
stateful: false,
}, {
arguments: [{ name: 'x', type: 'int' }, { name: 'y', type: 'int' }],
name: 'test',
payable: false,
returns: 'int',
stateful: false,
}, {
arguments: [],
name: 'getMap',
payable: false,
returns: { map: ['int', 'int'] },
stateful: false,
}],
kind: 'contract_main',
name: 'Identity',
payable: false,
state: { record: [{ name: 'z', type: 'int' }] },
type_defs: [],
},
},
externalEncodedAci: [{
namespace: { name: 'TestLib', type_defs: [] },
}],
interface: '\nmain contract Identity =\n record state = {z : int}\n entrypoint init : (int) => Identity.state\n entrypoint test : (int, int) => int\n entrypoint getMap : () => map(int, int)\n',
},
});
await fs.remove(descrPath);
});

Expand Down

0 comments on commit ea17f80

Please sign in to comment.