refactor: determine contract dependencies + add specs
This commit is contained in:
parent
4499fc6c13
commit
de9dff3397
|
@ -1,12 +1,15 @@
|
||||||
|
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
||||||
var readYaml = require('read-yaml');
|
var readYaml = require('read-yaml');
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var Blockchain = require('./blockchain.js');
|
var Blockchain = require('./blockchain.js');
|
||||||
|
var toposort = require('toposort');
|
||||||
|
|
||||||
ContractsConfig = function(files, blockchainConfig, web3) {
|
ContractsConfig = function(files, blockchainConfig, web3) {
|
||||||
this.all_contracts = [];
|
this.all_contracts = [];
|
||||||
this.contractDB = {};
|
this.contractDB = {};
|
||||||
this.contractFiles = files;
|
this.contractFiles = files;
|
||||||
this.web3 = web3;
|
this.web3 = web3;
|
||||||
|
this.contractDependencies = {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.web3.setProvider(new this.web3.providers.HttpProvider("http://" + blockchainConfig.rpcHost + ":" + blockchainConfig.rpcPort));
|
this.web3.setProvider(new this.web3.providers.HttpProvider("http://" + blockchainConfig.rpcHost + ":" + blockchainConfig.rpcPort));
|
||||||
|
@ -38,8 +41,27 @@ ContractsConfig.prototype.config = function(env) {
|
||||||
return this.contractConfig[env];
|
return this.contractConfig[env];
|
||||||
}
|
}
|
||||||
|
|
||||||
ContractsConfig.prototype.compileContracts = function() {
|
ContractsConfig.prototype.compileContracts = function(env) {
|
||||||
var contractFile, source, j;
|
var contractFile, source, j;
|
||||||
|
var contractsConfig = this.config(env);
|
||||||
|
|
||||||
|
if (contractsConfig != null) {
|
||||||
|
for (className in contractsConfig) {
|
||||||
|
options = contractsConfig[className];
|
||||||
|
if (options.args == null) continue;
|
||||||
|
|
||||||
|
ref = options.args;
|
||||||
|
for (j = 0; j < ref.length; j++) {
|
||||||
|
arg = ref[j];
|
||||||
|
if (arg[0] === "$") {
|
||||||
|
if (this.contractDependencies[className] === void 0) {
|
||||||
|
this.contractDependencies[className] = [];
|
||||||
|
}
|
||||||
|
this.contractDependencies[className].push(arg.substr(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (j = 0; j < this.contractFiles.length; j++) {
|
for (j = 0; j < this.contractFiles.length; j++) {
|
||||||
contractFile = this.contractFiles[j];
|
contractFile = this.contractFiles[j];
|
||||||
|
@ -53,6 +75,27 @@ ContractsConfig.prototype.compileContracts = function() {
|
||||||
this.contractDB[className] = contract;
|
this.contractDB[className] = contract;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.sortContracts();
|
||||||
|
}
|
||||||
|
|
||||||
|
ContractsConfig.prototype.sortContracts = function() {
|
||||||
|
var converted_dependencies = [], i;
|
||||||
|
|
||||||
|
for(contract in this.contractDependencies) {
|
||||||
|
var dependencies = this.contractDependencies[contract];
|
||||||
|
for(i=0; i < dependencies.length; i++) {
|
||||||
|
converted_dependencies.push([contract, dependencies[i]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var orderedDependencies = toposort(converted_dependencies).reverse();
|
||||||
|
|
||||||
|
this.all_contracts = this.all_contracts.sort(function(a,b) {
|
||||||
|
var order_a = orderedDependencies.indexOf(a);
|
||||||
|
var order_b = orderedDependencies.indexOf(b);
|
||||||
|
return order_a - order_b;
|
||||||
|
});;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = ContractsConfig
|
module.exports = ContractsConfig
|
||||||
|
|
|
@ -27,48 +27,10 @@ deployContracts = function(env, contractFiles, destFile) {
|
||||||
result = "web3.setProvider(new web3.providers.HttpProvider('http://" + blockchainConfig.rpcHost + ":" + blockchainConfig.rpcPort + "'));";
|
result = "web3.setProvider(new web3.providers.HttpProvider('http://" + blockchainConfig.rpcHost + ":" + blockchainConfig.rpcPort + "'));";
|
||||||
result += "web3.eth.defaultAccount = web3.eth.accounts[0];";
|
result += "web3.eth.defaultAccount = web3.eth.accounts[0];";
|
||||||
|
|
||||||
contractDependencies = {};
|
contractsManager.compileContracts(env);
|
||||||
|
|
||||||
if (contractsConfig != null) {
|
|
||||||
for (className in contractsConfig) {
|
|
||||||
options = contractsConfig[className];
|
|
||||||
if (options.args == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ref = options.args;
|
|
||||||
for (i = 0, len = ref.length; i < len; i++) {
|
|
||||||
arg = ref[i];
|
|
||||||
if (arg[0] === "$") {
|
|
||||||
if (contractDependencies[className] === void 0) {
|
|
||||||
contractDependencies[className] = [];
|
|
||||||
}
|
|
||||||
contractDependencies[className].push(arg.substr(1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
contractsManager.compileContracts();
|
|
||||||
all_contracts = contractsManager.all_contracts;
|
all_contracts = contractsManager.all_contracts;
|
||||||
contractDB = contractsManager.contractDB;
|
contractDB = contractsManager.contractDB;
|
||||||
|
contractDependencies = contractsManager.contractDependencies;
|
||||||
all_contracts.sort((function(_this) {
|
|
||||||
return function(a, b) {
|
|
||||||
var contract_1, contract_2;
|
|
||||||
contract_1 = contractDependencies[a];
|
|
||||||
contract_2 = contractDependencies[b];
|
|
||||||
if (indexOf.call(contract_1, a) >= 0 && indexOf.call(contract_2, b) >= 0) {
|
|
||||||
console.log("looks like you have a circular dependency between " + a + " and " + b);
|
|
||||||
return exit;
|
|
||||||
} else if (indexOf.call(contract_1, b) >= 0) {
|
|
||||||
return 1;
|
|
||||||
} else if (indexOf.call(contract_2, a) >= 0) {
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})(this));
|
|
||||||
|
|
||||||
deployedContracts = {};
|
deployedContracts = {};
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,8 @@
|
||||||
"sync-me": "^0.1.1",
|
"sync-me": "^0.1.1",
|
||||||
"python": "^0.0.4",
|
"python": "^0.0.4",
|
||||||
"methodmissing": "^0.0.3",
|
"methodmissing": "^0.0.3",
|
||||||
"jasmine": "^2.3.1"
|
"jasmine": "^2.3.1",
|
||||||
|
"toposort": "^0.2.10"
|
||||||
},
|
},
|
||||||
"author": "Iuri Matias <iuri.matias@gmail.com>",
|
"author": "Iuri Matias <iuri.matias@gmail.com>",
|
||||||
"contributors": [],
|
"contributors": [],
|
||||||
|
|
|
@ -56,6 +56,25 @@ describe('embark.config.contracts', function() {
|
||||||
assert.deepEqual(contractsConfig.all_contracts, [ "SimpleStorage", "AnotherStorage" ]);
|
assert.deepEqual(contractsConfig.all_contracts, [ "SimpleStorage", "AnotherStorage" ]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
context("contracts as arguments to other contracts", function() {
|
||||||
|
before(function() {
|
||||||
|
files = [
|
||||||
|
'test/support/contracts/wallet.sol',
|
||||||
|
'test/support/contracts/simple_storage.sol',
|
||||||
|
'test/support/contracts/another_storage.sol',
|
||||||
|
'test/support/contracts/wallets.sol'
|
||||||
|
]
|
||||||
|
contractsConfig = new Config.Contracts(files, blockchainConfig, web3);
|
||||||
|
contractsConfig.loadConfigFile('test/support/arguments.yml');
|
||||||
|
contractsConfig.compileContracts('development');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('add contracts to a list', function() {
|
||||||
|
assert.deepEqual(contractsConfig.all_contracts, [ "SimpleStorage", "AnotherStorage", "Wallet", "Wallets" ]);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
development:
|
||||||
|
Wallet:
|
||||||
|
args:
|
||||||
|
- $AnotherStorage
|
||||||
|
SimpleStorage:
|
||||||
|
args:
|
||||||
|
- 100
|
||||||
|
AnotherStorage:
|
||||||
|
args:
|
||||||
|
- 100
|
||||||
|
Wallets:
|
||||||
|
args:
|
||||||
|
- $Wallet
|
||||||
|
staging:
|
|
@ -0,0 +1,8 @@
|
||||||
|
contract Wallet {
|
||||||
|
address currency;
|
||||||
|
|
||||||
|
function Wallet(address c) {
|
||||||
|
currency = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
contract Wallets {
|
||||||
|
address wallet;
|
||||||
|
|
||||||
|
function Wallet(address w) {
|
||||||
|
wallet = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue