Skip to content

Commit

Permalink
Merge pull request #45 from harpagon210/mainnet
Browse files Browse the repository at this point in the history
fixing vm allocation
  • Loading branch information
harpagon210 authored Aug 6, 2019
2 parents 44bc181 + b70fc74 commit 491e205
Showing 1 changed file with 82 additions and 34 deletions.
116 changes: 82 additions & 34 deletions libs/SmartContracts.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ const DB_PLUGIN_ACTIONS = require('../plugins/Database.constants').PLUGIN_ACTION
const RESERVED_CONTRACT_NAMES = ['contract', 'blockProduction', 'null'];
const RESERVED_ACTIONS = ['createSSC'];

const JSVMs = [];
const MAXJSVMs = 5;

class SmartContracts {
// deploy the smart contract to the blockchain and initialize the database if needed
static async deploySmartContract(
Expand Down Expand Up @@ -54,31 +57,34 @@ class SmartContracts {
// this code template is used to manage the code of the smart contract
// this way we keep control of what can be executed in a smart contract
let codeTemplate = `
RegExp.prototype.constructor = function () { };
RegExp.prototype.exec = function () { };
RegExp.prototype.test = function () { };
let actions = {};
###ACTIONS###
const execute = async function () {
try {
if (api.action && typeof api.action === 'string' && typeof actions[api.action] === 'function') {
if (api.action !== 'createSSC') {
actions.createSSC = null;
function wrapper () {
RegExp.prototype.constructor = function () { };
RegExp.prototype.exec = function () { };
RegExp.prototype.test = function () { };
let actions = {};
###ACTIONS###
const execute = async function () {
try {
if (api.action && typeof api.action === 'string' && typeof actions[api.action] === 'function') {
if (api.action !== 'createSSC') {
actions.createSSC = null;
}
await actions[api.action](api.payload);
done(null);
} else {
done('invalid action');
}
await actions[api.action](api.payload);
done(null);
} else {
done('invalid action');
} catch (error) {
done(error);
}
} catch (error) {
done(error);
}
}
execute();
execute();
}
wrapper();
`;

// the code of the smart contarct comes as a Base64 encoded string
Expand Down Expand Up @@ -387,25 +393,67 @@ class SmartContracts {
}
}

static getJSVM(jsVMTimeout) {
let vm = null;

vm = JSVMs.find(v => v.inUse === false);

if (vm === undefined) {
if (JSVMs.length < MAXJSVMs) {
vm = {
vm: new VM({
timeout: jsVMTimeout,
sandbox: {
},
}),
inUse: true,
};
JSVMs.push(vm);
}
}

if (vm === undefined) {
vm = null;
} else {
// eslint-disable-next-line no-underscore-dangle
Object.keys(vm.vm._context).filter(key => key !== 'VMError' && key !== 'Buffer' && key !== 'api').forEach((key) => {
// eslint-disable-next-line no-underscore-dangle
delete vm.vm._context[key];
});
// eslint-disable-next-line no-underscore-dangle
vm.vm._context.api = {};
vm.inUse = true;
}

return vm;
}

// run the contractCode in a VM with the vmState as a state for the VM
static runContractCode(vmState, contractCode, jsVMTimeout) {
return new Promise((resolve) => {
const vm = SmartContracts.getJSVM(jsVMTimeout);
try {
// console.log('vmState', vmState)
// run the code in the VM
const vm = new VM({
timeout: jsVMTimeout,
sandbox: {
...vmState,
done: (error) => {
// console.log('error', error);
resolve(error);
},
},
});

vm.run(contractCode);
if (vm !== null) {
// eslint-disable-next-line no-underscore-dangle
Object.keys(vmState.api).forEach((key) => {
// eslint-disable-next-line no-underscore-dangle
vm.vm._context.api[key] = vmState.api[key];
});
// eslint-disable-next-line no-underscore-dangle
vm.vm._context.done = (error) => {
// console.log('error', error);
vm.inUse = false;
resolve(error);
};

vm.vm.run(contractCode);
} else {
resolve('no JS VM available');
}
} catch (err) {
// console.log('error', err);
vm.inUse = false;
resolve(err);
}
});
Expand Down

0 comments on commit 491e205

Please sign in to comment.