Skip to content
This repository has been archived by the owner on Sep 7, 2023. It is now read-only.

Commit

Permalink
(feature) Add support for state initialization to CLI
Browse files Browse the repository at this point in the history
Signed-off-by: Jerome Simeon <[email protected]>
  • Loading branch information
jeromesimeon committed Jun 9, 2018
1 parent d1f6b34 commit a6a7808
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 24 deletions.
11 changes: 6 additions & 5 deletions packages/ergo-cli/bin/ergo.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const Commands = require('../lib/commands');
const Logger = require('@accordproject/ergo-compiler/lib/logger');

require('yargs')
.command('compile', 'compile Ergo to JavaScript', (yargs) => {
.command('compile', 'compile Ergo contract to JavaScript', (yargs) => {
yargs.option('ergo', {
describe: 'path to the Ergo source'
});
Expand Down Expand Up @@ -48,15 +48,17 @@ require('yargs')
Logger.error(err.message + ' ' + JSON.stringify(err));
});
})
.command('execute', 'execute a contract', (yargs) => {
.command('execute', 'execute Ergo contract', (yargs) => {
yargs.option('contract', {
describe: 'path to the contract data'
});
yargs.option('request', {
describe: 'path to the request data'
}).array('request');
yargs.option('state', {
describe: 'path to the state data'
describe: 'path to the state data',
type: 'string',
default: null
});
yargs.option('ergo', {
describe: 'path to the Ergo file'
Expand All @@ -69,9 +71,8 @@ require('yargs')
});
}, (argv) => {
if (argv.verbose) {
Logger.info(`execute Ergo file ${argv.ergo} on contract data ${argv.contract} with request data ${argv.request} and CTOs ${argv.cto}`);
Logger.info(`execute Ergo contract ${argv.ergo} over data ${argv.contract} with request ${argv.request} and state ${argv.state} and CTOs ${argv.cto}`);
}

return Commands.execute(argv.ergo, argv.cto, argv.contract, argv.request, argv.state, argv.contractname)
.then((result) => {
Logger.info(JSON.stringify(result));
Expand Down
13 changes: 9 additions & 4 deletions packages/ergo-cli/lib/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const ErgoEngine = require('@accordproject/ergo-engine/lib/ergo-engine');
*/
class Commands {
/**
* Compile Ergo
* Compile Ergo contract
*
* @param {string} ergoPath path to the Ergo file
* @param {string} ctoPaths paths to CTO models
Expand All @@ -48,7 +48,7 @@ class Commands {
}

/**
* Execute Ergo
* Execute Ergo contract
*
* @param {string} ergoPath path to the Ergo file
* @param {string[]} ctoPaths paths to CTO models
Expand All @@ -71,9 +71,14 @@ class Commands {
for (let i = 0; i < requestsPath.length; i++) {
requestsJson.push(JSON.parse(Fs.readFileSync(requestsPath[i], 'utf8')));
}
const stateJson = JSON.parse(Fs.readFileSync(statePath, 'utf8'));
const firstRequest = requestsJson[0];
const initResponse = ErgoEngine.execute(ergoText,ctoTexts,contractJson,firstRequest,stateJson,contractName);
let initResponse;
if (statePath === null) {
initResponse = ErgoEngine.init(ergoText,ctoTexts,contractJson,firstRequest,contractName);
} else {
const stateJson = JSON.parse(Fs.readFileSync(statePath, 'utf8'));
initResponse = ErgoEngine.execute(ergoText,ctoTexts,contractJson,firstRequest,stateJson,contractName);
}
// Get all the other requests and chain execution through Promise.reduce()
const otherRequests = requestsJson.slice(1, requestsJson.length);
return otherRequests.reduce((promise,requestJson) => {
Expand Down
49 changes: 34 additions & 15 deletions packages/ergo-cli/test/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,63 +26,82 @@ describe('ergo', () => {
afterEach(() => {});

describe('#compilehello', function () {
it('should compile a smart Ergo clause', async function () {
it('should compile a smart Ergo contract', async function () {
const ergoPath = Path.resolve(__dirname, 'data/helloworld', 'logic.ergo');
const ctoPath = Path.resolve(__dirname, 'data/helloworld', 'model.cto');
const result = await Commands.compile(ergoPath, [ctoPath], 'javascript', false);
result.should.not.be.null;
});
it('should compile and link a smart Ergo clause', async function () {
it('should compile and link a smart Ergo contract', async function () {
const ergoPath = Path.resolve(__dirname, 'data/helloworld', 'logic.ergo');
const ctoPath = Path.resolve(__dirname, 'data/helloworld', 'model.cto');
const result = await Commands.compile(ergoPath, [ctoPath], 'javascript', true);
result.should.not.be.null;
});
it('should compile a smart Ergo clause without cto', async function () {
it('should compile a smart Ergo contract without cto', async function () {
const ergoPath = Path.resolve(__dirname, 'data/helloworld', 'logic.ergo');
const result = await Commands.compile(ergoPath, undefined, 'javascript', false);
result.should.not.be.null;
});
});
describe('#executehello', function () {
it('should execute a smart Ergo clause', async function () {
it('should execute a smart Ergo contract', async function () {
const ergoPath = Path.resolve(__dirname, 'data/helloworld', 'logic.ergo');
const ctoPath = Path.resolve(__dirname, 'data/helloworld', 'model.cto');
const clausePath = Path.resolve(__dirname, 'data/helloworld', 'contract.json');
const contractPath = Path.resolve(__dirname, 'data/helloworld', 'contract.json');
const requestPath = Path.resolve(__dirname, 'data/helloworld', 'request.json');
const statePath = Path.resolve(__dirname, 'data/helloworld', 'state.json');
const result = await Commands.execute(ergoPath, [ctoPath], clausePath, [requestPath], statePath, 'HelloWorld', false);
const result = await Commands.execute(ergoPath, [ctoPath], contractPath, [requestPath], statePath, 'HelloWorld', false);
result.response.output.should.equal('Hello Fred Blogs (Accord Project)');
});
it('should execute a smart Ergo clause without cto', async function () {
it('should execute a smart Ergo contract without cto', async function () {
const ergoPath = Path.resolve(__dirname, 'data/helloworld', 'logic.ergo');
const clausePath = Path.resolve(__dirname, 'data/helloworld', 'contract.json');
const contractPath = Path.resolve(__dirname, 'data/helloworld', 'contract.json');
const requestPath = Path.resolve(__dirname, 'data/helloworld', 'request.json');
const statePath = Path.resolve(__dirname, 'data/helloworld', 'state.json');
const result = await Commands.execute(ergoPath, undefined, clausePath, [requestPath], statePath, 'HelloWorld', false);
const result = await Commands.execute(ergoPath, undefined, contractPath, [requestPath], statePath, 'HelloWorld', false);
result.response.output.should.equal('Hello Fred Blogs (Accord Project)');
});
});
describe('#executehellostate', function () {
it('should execute a smart Ergo clause with state once', async function () {
it('should execute a smart Ergo contract with state once', async function () {
const ergoPath = Path.resolve(__dirname, 'data/helloworldstate', 'logic.ergo');
const ctoPath = Path.resolve(__dirname, 'data/helloworldstate', 'model.cto');
const clausePath = Path.resolve(__dirname, 'data/helloworldstate', 'contract.json');
const contractPath = Path.resolve(__dirname, 'data/helloworldstate', 'contract.json');
const requestPath = Path.resolve(__dirname, 'data/helloworldstate', 'request.json');
const statePath = Path.resolve(__dirname, 'data/helloworldstate', 'state.json');
const result = await Commands.execute(ergoPath, [ctoPath], clausePath, [requestPath], statePath, 'HelloWorldState', false);
const result = await Commands.execute(ergoPath, [ctoPath], contractPath, [requestPath], statePath, 'HelloWorldState', false);
result.response.output.should.equal('Hello Fred Blogs (Accord Project) (1)');
});
it('should execute a smart Ergo clause with state thrice', async function () {
it('should execute a smart Ergo contract with state thrice', async function () {
const ergoPath = Path.resolve(__dirname, 'data/helloworldstate', 'logic.ergo');
const ctoPath = Path.resolve(__dirname, 'data/helloworldstate', 'model.cto');
const clausePath = Path.resolve(__dirname, 'data/helloworldstate', 'contract.json');
const contractPath = Path.resolve(__dirname, 'data/helloworldstate', 'contract.json');
const requestPath = Path.resolve(__dirname, 'data/helloworldstate', 'request.json');
const statePath = Path.resolve(__dirname, 'data/helloworldstate', 'state.json');
const result = await Commands.execute(ergoPath, [ctoPath], clausePath, [requestPath,requestPath,requestPath], statePath, 'HelloWorldState', false);
const result = await Commands.execute(ergoPath, [ctoPath], contractPath, [requestPath,requestPath,requestPath], statePath, 'HelloWorldState', false);
result.response.output.should.equal('Hello Fred Blogs (Accord Project) (3)');
});
});
describe('#executeinstallmentsale', function () {
it('should initialize a smart Ergo contract state', async function () {
const ergoPath = Path.resolve(__dirname, 'data/installment-sale', 'logic.ergo');
const ctoPath = Path.resolve(__dirname, 'data/installment-sale', 'model.cto');
const contractPath = Path.resolve(__dirname, 'data/installment-sale', 'contract.json');
const requestInitPath = Path.resolve(__dirname, 'data/installment-sale', 'request-init.json');
const result = await Commands.execute(ergoPath, [ctoPath], contractPath, [requestInitPath], null, 'InstallmentSale', false);
result.state.balance_remaining.should.equal(10000.00);
});
it('should initialize a smart Ergo contract and execute one request', async function () {
const ergoPath = Path.resolve(__dirname, 'data/installment-sale', 'logic.ergo');
const ctoPath = Path.resolve(__dirname, 'data/installment-sale', 'model.cto');
const contractPath = Path.resolve(__dirname, 'data/installment-sale', 'contract.json');
const requestInitPath = Path.resolve(__dirname, 'data/installment-sale', 'request-init.json');
const requestPath = Path.resolve(__dirname, 'data/installment-sale', 'request.json');
const result = await Commands.execute(ergoPath, [ctoPath], contractPath, [requestInitPath,requestPath], null, 'InstallmentSale', false);
result.state.balance_remaining.should.equal(7612.499999999999);
});
});
describe('#parsecto', function () {
it('should parse CTO', async function () {
const ctoPath = Path.resolve(__dirname, 'data/helloworld', 'model.cto');
Expand Down

0 comments on commit a6a7808

Please sign in to comment.