Add support to recursively import contracts. If we have three contracts
1. A imports B
2. B imports C
Then prior to this PR, contract A would import contract B, and a remapping would be added to the contract so the compiler would know how to find contract B. However, contract B imports contracts C, and because the `parseFileForImport` method was not recursive, the remappings were not able to go one level deeper to remap the path to contract C, and thus the compiler would not know how to locate contract C, and would complain with the error `File outside of allowed directories.`
With the introduction of this PR, the `parseFileForImport` method is now recursive, and so any contract imported is also checked for it's own imports that can be remapped. Specifically, this use case is applicable when there is a dependency containing contracts that imports one of it's own dependency's contracts, ie:
```
pragma solididty ^0.5.0;
import "dependency-1/contract-1.sol";
```
where the dependencies look like:
```
|- node_modules
|--- dependency-1
|----- contract-1.sol <--- contains import "dependency-2/contract-2.sol"
|--- dependency-2
|----- contract-2.sol
```
Add unit tests that verify recursive imports work.
Add embark depdendency that installs a contract used in the recursive unit tests.
Remix_test-injected contract files were not correctly being tested due to an update in the `remix-tests` signature. I'm really not sure how tests were not completely bombing out during testing.
This PR introduces a few changes:
1. Ensure all contract files have been compiled before skipping compilation. This can occur if contract files have been added after a compilation round has already completed (ie in the tests).
2. Update solc tests to support latest `remix_tests.runTests` signature and include `userdoc` in compiled contracts.
3. Ensure `EmbarkJS` is reset before executing solc tests - like in the js tests, this is required for built EmbarkJS contract objects to behave correctly when it's functions are executed against the chain.
4. Refactor “all files already compiled” function.
BLOCKER: base branch `feat/replace-node-vm` must be merged in https://github.com/embark-framework/embark/pull/1234 before this can be merged.
Improve support for external requires. Allows external requires to be called like so:
```
Embark.events.on('runcode:ready', () => {
Embark.events.emit('runcode:register', 'generateClass', require('eth-contract-class'), false);
Embark.registerCustomContractGenerator(contract => {
return `
${contract.className} = generateClass(${JSON.stringify(contract.abiDefinition)}, '${contract.code}');
${contract.className}Instance = new ${contract.className}(web3, '${contract.deployedAddress}');
`;
});
});
Embark.events.once('contracts:deploy:afterAll', () => {
Embark.events.request('runcode:eval', 'SimpleStorageInstance', (err, SimpleStorageInstance) => {
if(err) return console.error(err);
SimpleStorageInstance.get().then((result) => {
console.log(`=====> SimpleStorageInstance.get(): ${result}`);
});
});
});
```
* Add `runcode:ready` that is fired when the VM is ready to accept registration of variables.
* Add support for registration of ES6 modules
* Add callback to `registerVar` and `setupNodeVm` in the `VM` class.
* Add support for retaining modified sandbox values across new VM instances.
* Add VM unit tests for external reaquries and modified sandbox state.
All code to be run in the console is run through a completely sandboxed VM2 instance, instead of the default Node VM.
VM2 will only allow whitelisted packages in a `require` statement. The whitelisted packages needed to run EmbarkJS scripts are:
```
[
"@babel/runtime-corejs2/helpers/interopRequireDefault",
"@babel/runtime-corejs2/core-js/json/stringify",
"@babel/runtime-corejs2/core-js/promise",
"@babel/runtime-corejs2/core-js/object/assign",
"eth-ens-namehash"
]
```
This can be circumvented in an Embark context (ie Plugin) if needed, for example in a Plugin constructor:
```
Embark.events.emit('runcode:register', 'require', require('lodash'), false);
Embark.events.request("runcode:eval", "_.head(['a', 'b', 'c', 'd']);", (err, result) => {
if(err) return console.log('========> error: ' + err);
console.log('========> ' + result);
});
```
Will emit `========> a`.
NOTE: Attempts to use this method to override `require` and `eval` should be handled by Embark and not allowed.
NOTE: VM2 seems to allow `eval`, however it is in a completely sandboxed environment, so I'm unsure that we need to be too concerned with this. Thoughts?
Refactor tests to use standalone instance of the newly created VM class, so that code is not evaluated through the console. This was done based on the new unit test case where accounts are redefined in a subsequent unit test, which was not originally working with the initial VM2 PR.
Refactor `codeRunner`, put all code-affecting logic in the `VM` class.
Changed `runCode` to `VM` and converted to TypeScript
Add unit tests for `VM`.
Check if IPFS config has `API.HTTPHeaders.Access-Control-Allow-Origin` before attempting to update it.
`ipfs init` produces a default configuration without a `API.HTTPHeaders.Access-Control-Allow-Origin` element in the JSON. This caused an error to be thrown when attempting to update the IPFS config to provide CORS values.
Regular transactions (aka “dev funds”) exist in embark as a workaround to a known bug in geth when using metamask. The workaround is to send a transaction at a regular interval (1.5s), which pushes through any transactions that were stuck. The problem is that the transaction logs and trace logs become cluttered and difficult to parse visually.
This PR disables regular transactions until the following conditions are met:
1. Embark is running geth
2. The user is running metamask in their browser
3. The user authenticates to the cockpit with `enableRegularTxs=1|true` in the query string.
A console warning is show in large letters in the browser with a link to the cockpit URL that includes the special query string to enable regular txs.
This could be extended later to have a button in the cockpit that start/stops regular txs. Or at least extended to allow disabling of regular txs once started.
Support standalone blockchain process.
Specifying large ether values in the configs was causing embark to crash as javascript could not handle the large integer after the value was converted to wei.
The fix involves converting all values to BigNumbers and then comparing and adding/subtracting BigNumbers from that point forward.
There are two specific components that this affected: `config/contracts > accounts > balance` and `config/blockchain > account > balance`. The contracts config is used to fund accounts for contract deployment while the blockchain config is used for dev_funds accounts.
JSON.stringify unknown log messages
Add a unit test in the test app that sets a large ether value in the config before contract deployment and ensures the account balance is the value specified in the config.
Prior to this commit, if subsequent unit tests contained different account configurations, the blockchain VM was essentially reset, however EmbarkJS was hanging on to the old providers it used from the previous configuation.
In addition, there is a limitation with `embark.registerActionForEvent` in that the action will be persisted across configuration changes. In our case, once the configuration was updated in a subsequent unit test, the directive subdomains would be attempted to be registered in ENS using the old configuration.
This commit does two things:
1) It resets the EmbarkJS.Blockchain and EmbarkJS.Names providers to the new chain configuration
2) Update to the ENS directives that prevents attempts at registered configured subdomains for previous configurations.
Send a message over IPC when a command is executed from the REPL so that
command history is immediately unified across `embark run` and one/more `embark
console`. Previously, for `embark console` to pick up a command entered in the
REPL of an `embark run` of which it was an IPC client it would have to be
restarted, and vice versa.