aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Browne <stephenalexbrowne@gmail.com>2018-05-22 04:56:32 +0800
committerAlex Browne <stephenalexbrowne@gmail.com>2018-06-07 03:39:39 +0800
commit577156fe5f63e581b101682d13b7e70e7a9336e5 (patch)
tree202d928d4888825a4ea1f24e2fd03368643c2966
parentda3f783a9ff69b059b1a98f502d980660d6bacab (diff)
downloaddexon-0x-contracts-577156fe5f63e581b101682d13b7e70e7a9336e5.tar.gz
dexon-0x-contracts-577156fe5f63e581b101682d13b7e70e7a9336e5.tar.zst
dexon-0x-contracts-577156fe5f63e581b101682d13b7e70e7a9336e5.zip
Use Geth for contract tests
-rw-r--r--packages/0x.js/src/0x.ts3
-rw-r--r--packages/contracts/test/utils/assertions.ts20
-rw-r--r--packages/dev-utils/src/blockchain_lifecycle.ts57
-rw-r--r--packages/dev-utils/src/web3_factory.ts2
-rw-r--r--packages/devnet/Dockerfile29
-rw-r--r--packages/devnet/README.md75
-rw-r--r--packages/devnet/genesis.json61
-rw-r--r--packages/devnet/node0/keystore/UTC--2018-05-11T21-29-08.903003751Z--5409ed021d9299bf6814279a6a1411a7e866a6311
-rw-r--r--packages/devnet/node0/keystore/UTC--2018-05-11T21-29-09.794553183Z--6ecbe1db9ef729cbe972c83fb886247691fb6beb1
-rw-r--r--packages/devnet/node0/keystore/UTC--2018-05-11T21-29-10.696351411Z--e36ea790bc9d7ab70c55260c66d52b1eca985f841
-rw-r--r--packages/devnet/node0/keystore/UTC--2018-05-11T21-29-11.479938556Z--e834ec434daba538cd1b9fe1582052b880bd7e631
-rw-r--r--packages/devnet/node0/keystore/UTC--2018-05-11T21-29-12.260348580Z--78dc5d2d739606d31509c31d654056a45185ecb61
-rw-r--r--packages/devnet/node0/keystore/UTC--2018-05-11T21-29-13.178294829Z--a8dda8d7f5310e4a9e24f8eba77e091ac264f8721
-rw-r--r--packages/devnet/node0/keystore/UTC--2018-05-11T21-29-13.960499696Z--06cef8e666768cc40cc78cf93d9611019ddcb6281
-rw-r--r--packages/devnet/node0/keystore/UTC--2018-05-11T21-29-14.757010386Z--4404ac8bd8f9618d27ad2f1485aa1b2cfd82482d1
-rw-r--r--packages/devnet/node0/keystore/UTC--2018-05-11T21-29-15.554233052Z--7457d5e02197480db681d3fdf256c7aca21bdc121
-rw-r--r--packages/devnet/node0/keystore/UTC--2018-05-11T21-29-16.342711541Z--91c987bf62d25945db517bdaa840a6c6613744021
-rw-r--r--packages/devnet/node0/keystore/UTC--2018-05-15T21-50-24.532037737Z--e8816898d851d5b61b7f950627d04d794c07ca371
-rw-r--r--packages/devnet/node0/password.txt11
-rwxr-xr-xpackages/devnet/run.sh23
-rw-r--r--packages/web3-wrapper/src/web3_wrapper.ts37
-rw-r--r--packages/web3-wrapper/test/web3_wrapper_test.ts19
22 files changed, 337 insertions, 11 deletions
diff --git a/packages/0x.js/src/0x.ts b/packages/0x.js/src/0x.ts
index 206954a0b..d19d04cbe 100644
--- a/packages/0x.js/src/0x.ts
+++ b/packages/0x.js/src/0x.ts
@@ -200,7 +200,8 @@ export class ZeroEx {
*/
public async awaitTransactionMinedAsync(
txHash: string,
- pollingIntervalMs: number = 1000,
+ // TODO(albrow): Change this back to 1000
+ pollingIntervalMs: number = 100,
timeoutMs?: number,
): Promise<TransactionReceiptWithDecodedLogs> {
// Hack: Get Web3Wrapper from ContractWrappers
diff --git a/packages/contracts/test/utils/assertions.ts b/packages/contracts/test/utils/assertions.ts
new file mode 100644
index 000000000..538a6e4fc
--- /dev/null
+++ b/packages/contracts/test/utils/assertions.ts
@@ -0,0 +1,20 @@
+import * as chai from 'chai';
+import * as _ from 'lodash';
+
+import { constants } from '../../util/constants';
+
+const expect = chai.expect;
+
+// throws if the given promise does not reject with one of two expected error
+// messages.
+export const expectRevertOrAlwaysFailingTransaction = <T>(p: Promise<T>) => {
+ return expect(p)
+ .to.be.rejected()
+ .then(e => {
+ expect(e).to.satisfy(
+ (err: Error) =>
+ _.includes(err.message, constants.REVERT) ||
+ _.includes(err.message, constants.ALWAYS_FAILING_TRANSACTION),
+ );
+ });
+};
diff --git a/packages/dev-utils/src/blockchain_lifecycle.ts b/packages/dev-utils/src/blockchain_lifecycle.ts
index 3e35de861..6e7957f10 100644
--- a/packages/dev-utils/src/blockchain_lifecycle.ts
+++ b/packages/dev-utils/src/blockchain_lifecycle.ts
@@ -1,6 +1,17 @@
import { Web3Wrapper } from '@0xproject/web3-wrapper';
+import * as _ from 'lodash';
import * as Web3 from 'web3';
+enum NodeType {
+ Geth = 'GETH',
+ Ganache = 'GANACHE',
+}
+
+// These are unique identifiers contained in the response of the
+// web3_clientVersion call.
+const GETH_VERSION_ID = 'Geth';
+const GANACHE_VERSION_ID = 'EthereumJS TestRPC';
+
export class BlockchainLifecycle {
private _web3Wrapper: Web3Wrapper;
private _snapshotIdsStack: number[];
@@ -8,17 +19,47 @@ export class BlockchainLifecycle {
this._web3Wrapper = web3Wrapper;
this._snapshotIdsStack = [];
}
- // TODO: In order to run these tests on an actual node, we should check if we are running against
- // TestRPC, if so, use snapshots, otherwise re-deploy contracts before every test
public async startAsync(): Promise<void> {
- const snapshotId = await this._web3Wrapper.takeSnapshotAsync();
- this._snapshotIdsStack.push(snapshotId);
+ const nodeType = await this._getNodeTypeAsync();
+ switch (nodeType) {
+ case NodeType.Ganache:
+ const snapshotId = await this._web3Wrapper.takeSnapshotAsync();
+ this._snapshotIdsStack.push(snapshotId);
+ break;
+ case NodeType.Geth:
+ const blockNumber = await this._web3Wrapper.getBlockNumberAsync();
+ this._snapshotIdsStack.push(blockNumber);
+ break;
+ default:
+ throw new Error(`Unknown node type: ${nodeType}`);
+ }
}
public async revertAsync(): Promise<void> {
- const snapshotId = this._snapshotIdsStack.pop() as number;
- const didRevert = await this._web3Wrapper.revertSnapshotAsync(snapshotId);
- if (!didRevert) {
- throw new Error(`Snapshot with id #${snapshotId} failed to revert`);
+ const nodeType = await this._getNodeTypeAsync();
+ switch (nodeType) {
+ case NodeType.Ganache:
+ const snapshotId = this._snapshotIdsStack.pop() as number;
+ const didRevert = await this._web3Wrapper.revertSnapshotAsync(snapshotId);
+ if (!didRevert) {
+ throw new Error(`Snapshot with id #${snapshotId} failed to revert`);
+ }
+ break;
+ case NodeType.Geth:
+ const blockNumber = this._snapshotIdsStack.pop() as number;
+ await this._web3Wrapper.setHeadAsync(blockNumber);
+ break;
+ default:
+ throw new Error(`Unknown node type: ${nodeType}`);
+ }
+ }
+ private async _getNodeTypeAsync(): Promise<NodeType> {
+ const version = await this._web3Wrapper.getNodeVersionAsync();
+ if (_.includes(version, GETH_VERSION_ID)) {
+ return NodeType.Geth;
+ } else if (_.includes(version, GANACHE_VERSION_ID)) {
+ return NodeType.Ganache;
+ } else {
+ throw new Error(`Unknown client version: ${version}`);
}
}
}
diff --git a/packages/dev-utils/src/web3_factory.ts b/packages/dev-utils/src/web3_factory.ts
index 12872c122..d8379825a 100644
--- a/packages/dev-utils/src/web3_factory.ts
+++ b/packages/dev-utils/src/web3_factory.ts
@@ -28,7 +28,7 @@ export const web3Factory = {
if (!hasAddresses) {
provider.addProvider(new EmptyWalletSubprovider());
}
- provider.addProvider(new FakeGasEstimateSubprovider(constants.GAS_LIMIT));
+ // provider.addProvider(new FakeGasEstimateSubprovider(constants.GAS_LIMIT));
const logger = {
log: (arg: any) => {
fs.appendFileSync('ganache.log', `${arg}\n`);
diff --git a/packages/devnet/Dockerfile b/packages/devnet/Dockerfile
new file mode 100644
index 000000000..1115112bd
--- /dev/null
+++ b/packages/devnet/Dockerfile
@@ -0,0 +1,29 @@
+FROM alpine:3.7
+
+RUN \
+ apk add --update go git make gcc musl-dev linux-headers ca-certificates && \
+ # TODO(albrow): Change the Git URL and branch once we have all relvant PRs
+ # merged to upstream.
+ git clone --depth 1 --branch sethead-txpool-fix https://github.com/0xProject/go-ethereum && \
+ (cd go-ethereum && make geth) && \
+ cp go-ethereum/build/bin/geth /geth && \
+ apk del go git make gcc musl-dev linux-headers && \
+ rm -rf /go-ethereum && rm -rf /var/cache/apk/*
+
+RUN mkdir ~/devnet
+WORKDIR ~/devnet
+
+COPY genesis.json .
+COPY node0/ ./node0
+COPY run.sh .
+
+RUN /geth --datadir node0/ init genesis.json
+
+EXPOSE 8501
+EXPOSE 30310
+
+ENTRYPOINT ./run.sh
+
+# TODO(albrow): Send a single transaction to increment the block number from 0
+# to 1. This seems to prevent bugs in the tests. (There's probably something
+# Geth doesn't like about getting reset back to block 0).
diff --git a/packages/devnet/README.md b/packages/devnet/README.md
new file mode 100644
index 000000000..6dfffeae7
--- /dev/null
+++ b/packages/devnet/README.md
@@ -0,0 +1,75 @@
+## 0x Devnet
+
+A private, single-node PoA Ethereum network for testing purposes only. It uses
+Geth and the PoA implementation called "Clique".
+
+## Installation
+
+The devnet requires Docker to run (the latest version is recommended).
+
+In the package root directory, run:
+
+```
+docker build -t 0x-devnet .
+```
+
+## Usage
+
+To start the network, run:
+
+```
+docker run -it --rm -p 8501:8501 0x-devnet
+```
+
+Depending on your OS and how you installed docker, you may need to prefix any
+docker commands with `sudo`.
+
+The Docker container exposes the JSON RPC API at port 8501, and this is the
+primary way you are expected to interact with the devnet. The following
+endpoints are supported: `personal,db,eth,net,web3,txpool,miner,debug`.
+
+You can stop the network with `docker stop` and it will automatically clean up
+after itself. (`docker stop` typically requires you to use `docker ps` to find
+the name of the currently running container).
+
+### Configuration
+
+The devnet network only has a single node and using PoA instead of PoW. That
+means that one node, called the "sealer", is the ultimate authority for
+validating transactions and adding new blocks to the chain. Since there is no
+PoW it also means that mining does not require significant computational
+resources. You can learn more about PoA and the Geth-specific implementation
+called "Clique" in [EIP-225](https://github.com/ethereum/EIPs/issues/225).
+
+The address of the "sealer" is `0xe8816898d851d5b61b7f950627d04d794c07ca37`. The
+password associated with the account is "password" and the (encrypted) private
+keys are visible in the **node0/keystore** directory. This account is already
+"unlocked" in the Geth node by default, so you can do things like sign and send
+transactions from this account using the JSON RPC endpoints directly.
+
+There are also a number of other addresses that have hard-coded starting
+balances for testing purposes. You can see the details in the **genesis.json**
+file. All of these accounts are also unlocked by default.
+
+### Mining
+
+The node will automatically (nearly instantly) mine a block whenever new
+transactions are added to the transaction pool. If there are no transactions in
+the pool, it will wait.
+
+To stop mining, use the
+[`miner.stop`](https://github.com/ethereum/go-ethereum/wiki/Management-APIs#miner_stop)
+method.
+
+To start mining again, you can use the
+[`miner.start`](https://github.com/ethereum/go-ethereum/wiki/Management-APIs#miner_start)
+JSON RPC method.
+
+## Contributing
+
+We strongly recommend that the community help us make improvements and determine
+the future direction of the protocol. To report bugs within this package, please
+create an issue in this repository.
+
+Please read our [contribution guidelines](../../CONTRIBUTING.md) before getting
+started.
diff --git a/packages/devnet/genesis.json b/packages/devnet/genesis.json
new file mode 100644
index 000000000..85512b398
--- /dev/null
+++ b/packages/devnet/genesis.json
@@ -0,0 +1,61 @@
+{
+ "config": {
+ "chainId": 50,
+ "homesteadBlock": 1,
+ "eip150Block": 2,
+ "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "eip155Block": 3,
+ "eip158Block": 3,
+ "byzantiumBlock": 4,
+ "clique": {
+ "period": 0,
+ "epoch": 30000
+ }
+ },
+ "nonce": "0x0",
+ "timestamp": "0x5af1ffac",
+ "extraData":
+ "0x0000000000000000000000000000000000000000000000000000000000000000e8816898d851d5b61b7f950627d04d794c07ca370000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "gasLimit": "0x47b760",
+ "difficulty": "0x1",
+ "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "coinbase": "0x0000000000000000000000000000000000000000",
+ "alloc": {
+ "0xe8816898d851d5b61b7f950627d04d794c07ca37": {
+ "balance": "0x56BC75E2D63100000"
+ },
+ "0x5409ed021d9299bf6814279a6a1411a7e866a631": {
+ "balance": "0x56BC75E2D63100000"
+ },
+ "0x6ecbe1db9ef729cbe972c83fb886247691fb6beb": {
+ "balance": "0x56BC75E2D63100000"
+ },
+ "0xe36ea790bc9d7ab70c55260c66d52b1eca985f84": {
+ "balance": "0x56BC75E2D63100000"
+ },
+ "0xe834ec434daba538cd1b9fe1582052b880bd7e63": {
+ "balance": "0x56BC75E2D63100000"
+ },
+ "0x78dc5d2d739606d31509c31d654056a45185ecb6": {
+ "balance": "0x56BC75E2D63100000"
+ },
+ "0xa8dda8d7f5310e4a9e24f8eba77e091ac264f872": {
+ "balance": "0x56BC75E2D63100000"
+ },
+ "0x06cef8e666768cc40cc78cf93d9611019ddcb628": {
+ "balance": "0x56BC75E2D63100000"
+ },
+ "0x4404ac8bd8f9618d27ad2f1485aa1b2cfd82482d": {
+ "balance": "0x56BC75E2D63100000"
+ },
+ "0x7457d5e02197480db681d3fdf256c7aca21bdc12": {
+ "balance": "0x56BC75E2D63100000"
+ },
+ "0x91c987bf62d25945db517bdaa840a6c661374402": {
+ "balance": "0x56BC75E2D63100000"
+ }
+ },
+ "number": "0x0",
+ "gasUsed": "0x0",
+ "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
+}
diff --git a/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-08.903003751Z--5409ed021d9299bf6814279a6a1411a7e866a631 b/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-08.903003751Z--5409ed021d9299bf6814279a6a1411a7e866a631
new file mode 100644
index 000000000..32c4002e0
--- /dev/null
+++ b/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-08.903003751Z--5409ed021d9299bf6814279a6a1411a7e866a631
@@ -0,0 +1 @@
+{"address":"5409ed021d9299bf6814279a6a1411a7e866a631","crypto":{"cipher":"aes-128-ctr","ciphertext":"7c7bdd62b303eb3a42d5d8e935825ed5a05a47cb2cef71e346c61b1bd582f1aa","cipherparams":{"iv":"7fd6c9d9f9893f2c480735b5386b6d75"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"79cc86edc3a668845a68fabb3913710b7504922e47aac8513ab3d6a28d090218"},"mac":"8a593ae0d0b964e47625bc964b6d389f5687f5bde631b4913136db4ab1b8083e"},"id":"29f637ba-6a65-4401-a0d1-30e1554bd776","version":3}
diff --git a/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-09.794553183Z--6ecbe1db9ef729cbe972c83fb886247691fb6beb b/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-09.794553183Z--6ecbe1db9ef729cbe972c83fb886247691fb6beb
new file mode 100644
index 000000000..ba84ccfd2
--- /dev/null
+++ b/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-09.794553183Z--6ecbe1db9ef729cbe972c83fb886247691fb6beb
@@ -0,0 +1 @@
+{"address":"6ecbe1db9ef729cbe972c83fb886247691fb6beb","crypto":{"cipher":"aes-128-ctr","ciphertext":"ecaf4f2839d74d92e2cb87c2fc7d52862661b46e697d70acfbe43f0893db73ed","cipherparams":{"iv":"7641c3a107228f8a901c07a07ea1f70d"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"c67c9fb30648df6985c0490b6603382147e7dc1ea28ca8c934af4a453ec0555b"},"mac":"985dca9ce65ad400fa4c9009742be2d409f402fe05203fc1278cfd1451729e8d"},"id":"e8634edc-08e6-415e-8d65-7985c4c4a05c","version":3}
diff --git a/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-10.696351411Z--e36ea790bc9d7ab70c55260c66d52b1eca985f84 b/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-10.696351411Z--e36ea790bc9d7ab70c55260c66d52b1eca985f84
new file mode 100644
index 000000000..e889c38b3
--- /dev/null
+++ b/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-10.696351411Z--e36ea790bc9d7ab70c55260c66d52b1eca985f84
@@ -0,0 +1 @@
+{"address":"e36ea790bc9d7ab70c55260c66d52b1eca985f84","crypto":{"cipher":"aes-128-ctr","ciphertext":"49f89d7d612049f5f3581fc7c97d32ec9c9a2ca3c11165587139f16bfb29de6b","cipherparams":{"iv":"9767e0687a097c5b57e9cb30eec9bc0a"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"3e8f23332df99d519b602a0f6f4724338ba3fd9e7e313c337a92ffd1cafa19f1"},"mac":"4892051a669d45bb7de32a5eab63ee8fe52485a02218ce1806515da2adbd6584"},"id":"3488ad36-4a9d-4282-8651-7939b822429d","version":3}
diff --git a/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-11.479938556Z--e834ec434daba538cd1b9fe1582052b880bd7e63 b/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-11.479938556Z--e834ec434daba538cd1b9fe1582052b880bd7e63
new file mode 100644
index 000000000..c12742c54
--- /dev/null
+++ b/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-11.479938556Z--e834ec434daba538cd1b9fe1582052b880bd7e63
@@ -0,0 +1 @@
+{"address":"e834ec434daba538cd1b9fe1582052b880bd7e63","crypto":{"cipher":"aes-128-ctr","ciphertext":"a8ae3896739c63fc3bfe034277f6a1924a1c0ddc3f6747391dada8e61e15a928","cipherparams":{"iv":"f4f4d786cd3650a428a8bac5a6c824b1"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"9acecc321bcab9b69ffdea494b8894ad0221c30f05c17d2302e315db8708ecc6"},"mac":"fc416b8f539fdc1e39e87a3bd2a69b04455875de701ced60cc8948b222171380"},"id":"0d9703e8-14fc-45d0-a425-2c40b8ae846a","version":3}
diff --git a/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-12.260348580Z--78dc5d2d739606d31509c31d654056a45185ecb6 b/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-12.260348580Z--78dc5d2d739606d31509c31d654056a45185ecb6
new file mode 100644
index 000000000..691e31dcf
--- /dev/null
+++ b/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-12.260348580Z--78dc5d2d739606d31509c31d654056a45185ecb6
@@ -0,0 +1 @@
+{"address":"78dc5d2d739606d31509c31d654056a45185ecb6","crypto":{"cipher":"aes-128-ctr","ciphertext":"25e90e593f08e9e3adc426c8685d90db5d1c04957e9dc8d5fab4ae30c3306b61","cipherparams":{"iv":"72ece22297a27363e795b678bcbd6be5"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"2201502b9d3c4e2076d9d15bfd9da3a6c75d9e2e574aabb29c3bc5a3b5ec55a5"},"mac":"13d709ed4bd2f5bf4973fc1373f8434835f0d12dc99b32c6fc14d9df7f41c62d"},"id":"3902dff4-5681-4646-b825-849f96efeec5","version":3}
diff --git a/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-13.178294829Z--a8dda8d7f5310e4a9e24f8eba77e091ac264f872 b/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-13.178294829Z--a8dda8d7f5310e4a9e24f8eba77e091ac264f872
new file mode 100644
index 000000000..9054e0019
--- /dev/null
+++ b/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-13.178294829Z--a8dda8d7f5310e4a9e24f8eba77e091ac264f872
@@ -0,0 +1 @@
+{"address":"a8dda8d7f5310e4a9e24f8eba77e091ac264f872","crypto":{"cipher":"aes-128-ctr","ciphertext":"0d67c13cf0b130e8ffa1aaca5df372f727164e633f8e0e28a3e54d0884ffb568","cipherparams":{"iv":"619cd539cda9f40abb45bba00b5fe53d"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"4effcd9b6fe71ee31cfe9057290154329b9af3acb6dcc46be7f78b5b9dcd3f42"},"mac":"c6eecd25944f4250b7b875d76bfbb60cc4e8db1d081621d1a2ddb72ea4e52a6d"},"id":"556bd3f1-1e5b-47a4-9b6e-448b9989d7d3","version":3}
diff --git a/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-13.960499696Z--06cef8e666768cc40cc78cf93d9611019ddcb628 b/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-13.960499696Z--06cef8e666768cc40cc78cf93d9611019ddcb628
new file mode 100644
index 000000000..0870638dd
--- /dev/null
+++ b/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-13.960499696Z--06cef8e666768cc40cc78cf93d9611019ddcb628
@@ -0,0 +1 @@
+{"address":"06cef8e666768cc40cc78cf93d9611019ddcb628","crypto":{"cipher":"aes-128-ctr","ciphertext":"38c9ca150932dc8c5ec5c65796425b2de98295cae64db08b816da2c06fc52c20","cipherparams":{"iv":"512127e8e606c481612473e7bc4d38f1"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"16c4cabfd13cae2df66d8ff9acc7f503c95c808b00d0bb6a12932203889c679b"},"mac":"52297b496e8751627dea1ee17bf5cbea1926f90bcde3ffc8baa089184672f875"},"id":"31102097-86e4-4e19-ad73-03c3de67bf3b","version":3}
diff --git a/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-14.757010386Z--4404ac8bd8f9618d27ad2f1485aa1b2cfd82482d b/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-14.757010386Z--4404ac8bd8f9618d27ad2f1485aa1b2cfd82482d
new file mode 100644
index 000000000..5f28db78f
--- /dev/null
+++ b/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-14.757010386Z--4404ac8bd8f9618d27ad2f1485aa1b2cfd82482d
@@ -0,0 +1 @@
+{"address":"4404ac8bd8f9618d27ad2f1485aa1b2cfd82482d","crypto":{"cipher":"aes-128-ctr","ciphertext":"ca7aedbacc960fc0fcb418606d7bdf042c36cc2808a5c94ac222cc0b44a9970d","cipherparams":{"iv":"3b1fe5da1cf5d6cd2ceaaf24c008c897"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"a94e4d41d77ff6dc54beda30c7a46d8f3cc312ebeffa0352d679f7e3fc5301dc"},"mac":"9a82bf60103d05878f8af3c07765c22cba3df9b1c4376eaf859e47b805666e42"},"id":"ab68c67b-e15a-4ade-b3d9-2180a32b28fe","version":3}
diff --git a/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-15.554233052Z--7457d5e02197480db681d3fdf256c7aca21bdc12 b/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-15.554233052Z--7457d5e02197480db681d3fdf256c7aca21bdc12
new file mode 100644
index 000000000..2a2c0194a
--- /dev/null
+++ b/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-15.554233052Z--7457d5e02197480db681d3fdf256c7aca21bdc12
@@ -0,0 +1 @@
+{"address":"7457d5e02197480db681d3fdf256c7aca21bdc12","crypto":{"cipher":"aes-128-ctr","ciphertext":"720dcc2889c7b3636f9f659650181b0d46d82420460e23454277273f528baaee","cipherparams":{"iv":"1510028e2b9988d1a73b71cbb692d085"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"5db2b62f4d1f55a3f24c014c4f23f3ec9a2992dca6c2a89c24a566f99a079396"},"mac":"22c6fb134fd0a748195ea83e9ccb490ab2c9a3e8761f9d74ea6d02abbdeb8a43"},"id":"704c31f8-8ca2-4b49-9fdc-5923f5712dad","version":3}
diff --git a/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-16.342711541Z--91c987bf62d25945db517bdaa840a6c661374402 b/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-16.342711541Z--91c987bf62d25945db517bdaa840a6c661374402
new file mode 100644
index 000000000..edc6d7531
--- /dev/null
+++ b/packages/devnet/node0/keystore/UTC--2018-05-11T21-29-16.342711541Z--91c987bf62d25945db517bdaa840a6c661374402
@@ -0,0 +1 @@
+{"address":"91c987bf62d25945db517bdaa840a6c661374402","crypto":{"cipher":"aes-128-ctr","ciphertext":"8f461f3c74643f382f7fc1f71719d5a89ed8cf75854d8a1b53e133997b53a386","cipherparams":{"iv":"cf595fb7680d36b4f5a01599ee54d2d1"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"73a9e599369d2bfaedd044559415147240c3517f6cd1dec8f77a98993d1ceaf8"},"mac":"c8be4dc59ad28d40f7b549a6b72834d149c84d67dc35e687676bbee0e07be395"},"id":"21cca6fb-7876-4e39-a986-a0a37f90da6d","version":3}
diff --git a/packages/devnet/node0/keystore/UTC--2018-05-15T21-50-24.532037737Z--e8816898d851d5b61b7f950627d04d794c07ca37 b/packages/devnet/node0/keystore/UTC--2018-05-15T21-50-24.532037737Z--e8816898d851d5b61b7f950627d04d794c07ca37
new file mode 100644
index 000000000..cd2c97a88
--- /dev/null
+++ b/packages/devnet/node0/keystore/UTC--2018-05-15T21-50-24.532037737Z--e8816898d851d5b61b7f950627d04d794c07ca37
@@ -0,0 +1 @@
+{"address":"e8816898d851d5b61b7f950627d04d794c07ca37","crypto":{"cipher":"aes-128-ctr","ciphertext":"1ff4add6955cba7ddaf29f66d7d21c5e1d714ef6191fbc651ae60f2ea3c95e8f","cipherparams":{"iv":"3ff869fbdbe1a523cdb327780365976e"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"7372dbae5fb318f8684902e099c311d4188721d677974d729711762c7ef6030c"},"mac":"485fa5dc701067782baa1589716a53110c7f917eb259e35ebca7265bbb7150b1"},"id":"89edb004-5b00-4607-a3af-a0d9ab9b1c34","version":3} \ No newline at end of file
diff --git a/packages/devnet/node0/password.txt b/packages/devnet/node0/password.txt
new file mode 100644
index 000000000..9842d2661
--- /dev/null
+++ b/packages/devnet/node0/password.txt
@@ -0,0 +1,11 @@
+password
+password
+password
+password
+password
+password
+password
+password
+password
+password
+password
diff --git a/packages/devnet/run.sh b/packages/devnet/run.sh
new file mode 100755
index 000000000..5d867cf9c
--- /dev/null
+++ b/packages/devnet/run.sh
@@ -0,0 +1,23 @@
+set -e
+
+# Create log directory for Geth
+mkdir -p /var/log
+
+# Start Geth in background and redirect output to log file
+/geth --datadir node0/ --syncmode 'full' --nat none --nodiscover --port 30310 --txpool.journal '' \
+ --rpc --rpcaddr '0.0.0.0' --rpcport 8501 --rpcapi 'personal,db,eth,net,web3,txpool,miner,debug' \
+ --networkid 50 --gasprice '2000000000' --targetgaslimit '0x47b760' --mine --etherbase '0xe8816898d851d5b61b7f950627d04d794c07ca37' \
+ --unlock '0xe8816898d851d5b61b7f950627d04d794c07ca37,0x5409ed021d9299bf6814279a6a1411a7e866a631,0x6ecbe1db9ef729cbe972c83fb886247691fb6beb,0xe36ea790bc9d7ab70c55260c66d52b1eca985f84,0xe834ec434daba538cd1b9fe1582052b880bd7e63,0x78dc5d2d739606d31509c31d654056a45185ecb6,0xa8dda8d7f5310e4a9e24f8eba77e091ac264f872,0x06cef8e666768cc40cc78cf93d9611019ddcb628,0x4404ac8bd8f9618d27ad2f1485aa1b2cfd82482d,0x7457d5e02197480db681d3fdf256c7aca21bdc12,0x91c987bf62d25945db517bdaa840a6c661374402' \
+ --password=node0/password.txt \
+ > /var/log/geth &
+
+# Wait for Geth to unlock the first account
+sleep 2
+
+# Send a single transaction. We have to do this so that debug.setHead works
+# correctly. (Geth does not seem to like debug.setHead(0), so by sending this
+# transaction we increase the current block number to 1).
+/geth --datadir node0/ attach --exec 'eth.sendTransaction({"from": "0xe8816898d851d5b61b7f950627d04d794c07ca37", "to": "0x84bd1cfa409cb0bb9b23b8b1a33515b4ac00a0af", "value": "0x1"})'
+
+# Use tail to re-attach to the log file and actually see the output.
+tail -f /var/log/geth
diff --git a/packages/web3-wrapper/src/web3_wrapper.ts b/packages/web3-wrapper/src/web3_wrapper.ts
index 3de152df1..d922c80cd 100644
--- a/packages/web3-wrapper/src/web3_wrapper.ts
+++ b/packages/web3-wrapper/src/web3_wrapper.ts
@@ -281,7 +281,6 @@ export class Web3Wrapper {
};
const payload = {
jsonrpc: '2.0',
- id: this._jsonRpcRequestId++,
method: 'eth_getLogs',
params: [serializedFilter],
};
@@ -403,8 +402,44 @@ export class Web3Wrapper {
}
return receipt;
}
+ /**
+ * Start the CPU mining process with the given number of threads and
+ * generate a new DAG if need be.
+ * @param threads The number of threads to mine on.
+ */
+ public async minerStartAsync(threads: number = 1): Promise<void> {
+ await this._sendRawPayloadAsync<boolean>({
+ method: 'miner_start',
+ params: [threads],
+ });
+ }
+ /**
+ * Stop the CPU mining process.
+ * @param threads The number of threads to mine on.
+ */
+ public async minerStopAsync(): Promise<void> {
+ await this._sendRawPayloadAsync<boolean>({ method: 'miner_stop', params: [] });
+ }
+ /**
+ * Returns true if client is actively mining new blocks.
+ * @returns A boolean indicating whether the node is currently mining.
+ */
+ public async isMiningAsync(): Promise<boolean> {
+ const isMining = await promisify<boolean>(this._web3.eth.getMining)();
+ return isMining;
+ }
+ /**
+ * Sets the current head of the local chain by block number. Note, this is a
+ * destructive action and may severely damage your chain. Use with extreme
+ * caution.
+ * @param blockNumber The block number to reset to.
+ */
+ public async setHeadAsync(blockNumber: number): Promise<void> {
+ await this._sendRawPayloadAsync<void>({ method: 'debug_setHead', params: [this._web3.toHex(blockNumber)] });
+ }
private async _sendRawPayloadAsync<A>(payload: Partial<JSONRPCRequestPayload>): Promise<A> {
const sendAsync = this._web3.currentProvider.sendAsync.bind(this._web3.currentProvider);
+ payload.id = this._jsonRpcRequestId++;
const response = await promisify<JSONRPCResponsePayload>(sendAsync)(payload);
const result = response.result;
return result;
diff --git a/packages/web3-wrapper/test/web3_wrapper_test.ts b/packages/web3-wrapper/test/web3_wrapper_test.ts
index 326efe654..1843bcf2c 100644
--- a/packages/web3-wrapper/test/web3_wrapper_test.ts
+++ b/packages/web3-wrapper/test/web3_wrapper_test.ts
@@ -2,6 +2,7 @@ import * as chai from 'chai';
import * as Ganache from 'ganache-core';
import 'make-promises-safe';
import 'mocha';
+import * as Web3 from 'web3';
import { Web3Wrapper } from '../src';
@@ -37,4 +38,22 @@ describe('Web3Wrapper tests', () => {
expect(networkId).to.be.equal(NETWORK_ID);
});
});
+ describe('mining functions', () => {
+ it('starts and stops the miner', async () => {
+ // Note: depending on our provider, the miner may or may not already
+ // be mining. To account for both conditions, we have what might
+ // look like too many stops and starts here, but it is necessary.
+ await web3Wrapper.minerStopAsync();
+ let isMining = await web3Wrapper.isMiningAsync();
+ expect(isMining).to.be.false();
+ await web3Wrapper.minerStartAsync(1);
+ isMining = await web3Wrapper.isMiningAsync();
+ expect(isMining).to.be.true();
+ isMining = await web3Wrapper.isMiningAsync();
+ expect(isMining).to.be.true();
+ await web3Wrapper.minerStopAsync();
+ isMining = await web3Wrapper.isMiningAsync();
+ expect(isMining).to.be.false();
+ });
+ });
});