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 fs = require('fs');
|
||||
var Blockchain = require('./blockchain.js');
|
||||
var toposort = require('toposort');
|
||||
|
||||
ContractsConfig = function(files, blockchainConfig, web3) {
|
||||
this.all_contracts = [];
|
||||
this.contractDB = {};
|
||||
this.contractFiles = files;
|
||||
this.web3 = web3;
|
||||
this.contractDependencies = {};
|
||||
|
||||
try {
|
||||
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];
|
||||
}
|
||||
|
||||
ContractsConfig.prototype.compileContracts = function() {
|
||||
ContractsConfig.prototype.compileContracts = function(env) {
|
||||
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++) {
|
||||
contractFile = this.contractFiles[j];
|
||||
|
@ -53,6 +75,27 @@ ContractsConfig.prototype.compileContracts = function() {
|
|||
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
|
||||
|
|
|
@ -27,48 +27,10 @@ deployContracts = function(env, contractFiles, destFile) {
|
|||
result = "web3.setProvider(new web3.providers.HttpProvider('http://" + blockchainConfig.rpcHost + ":" + blockchainConfig.rpcPort + "'));";
|
||||
result += "web3.eth.defaultAccount = web3.eth.accounts[0];";
|
||||
|
||||
contractDependencies = {};
|
||||
|
||||
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();
|
||||
contractsManager.compileContracts(env);
|
||||
all_contracts = contractsManager.all_contracts;
|
||||
contractDB = contractsManager.contractDB;
|
||||
|
||||
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));
|
||||
contractDependencies = contractsManager.contractDependencies;
|
||||
|
||||
deployedContracts = {};
|
||||
|
||||
|
|
|
@ -34,7 +34,8 @@
|
|||
"sync-me": "^0.1.1",
|
||||
"python": "^0.0.4",
|
||||
"methodmissing": "^0.0.3",
|
||||
"jasmine": "^2.3.1"
|
||||
"jasmine": "^2.3.1",
|
||||
"toposort": "^0.2.10"
|
||||
},
|
||||
"author": "Iuri Matias <iuri.matias@gmail.com>",
|
||||
"contributors": [],
|
||||
|
|
|
@ -56,6 +56,25 @@ describe('embark.config.contracts', function() {
|
|||
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