Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Commit

Permalink
Merge branch 'develop' into time-revert
Browse files Browse the repository at this point in the history
  • Loading branch information
benjamincburns authored Apr 12, 2018
2 parents 834f0fa + 7756140 commit ba4f4b3
Show file tree
Hide file tree
Showing 53 changed files with 9,424 additions and 1,287 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ TODO
.tern-project
.DS_Store
.tern-port
.vscode
yarn.lock
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
language: node_js
node_js:
- "6"
- "6.1"
- "node"
- "lts/boron"

addons:
apt:
Expand Down
128 changes: 34 additions & 94 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
[![npm](https://img.shields.io/npm/v/ethereumjs-testrpc.svg)]()
[![npm](https://img.shields.io/npm/dm/ethereumjs-testrpc.svg)]()
[![Build Status](https://travis-ci.org/ethereumjs/testrpc.svg?branch=master)](https://travis-ci.org/ethereumjs/testrpc)
[![npm](https://img.shields.io/npm/v/ganache-core.svg)]()
[![npm](https://img.shields.io/npm/dm/ganache-core.svg)]()
[![Build Status](https://travis-ci.org/trufflesuite/ganache-core.svg?branch=master)](https://travis-ci.org/trufflesuite/ganache-core)
# Ganache Core

*NOTE: As of version `3.0.2`, `testrpc` requires at least `Node 6.9.1` to run - this is because the `[email protected]` dependency is now shipping using ES2015 language features.*

# Welcome to `testrpc`

`testrpc` is a Node.js based Ethereum client for testing and development. It uses ethereumjs to simulate full client behavior and make developing Ethereum applications much faster. It also includes all popular RPC functions and features (like events) and can be run deterministically to make development a breeze.
This is the core code that powers the Ganache application and the the Ganache command line tool.

# INSTALL

`testrpc` is written in Javascript and distributed as a Node package via `npm`. Make sure you have Node.js (>= v6.9.1) installed, and your environment is capable of installing and compiling `npm` modules.
`ganache-core` is written in Javascript and distributed as a Node package via `npm`. Make sure you have Node.js (>= v6.11.5) installed, and your environment is capable of installing and compiling `npm` modules.

**macOS** Make sure you have the XCode Command Line Tools installed. These are needed in general to be able to compile most C based languages on your machine, as well as many npm modules.

Expand All @@ -20,100 +17,55 @@


```Bash
npm install -g ethereumjs-testrpc
npm install ganache-core
```

Having problems? Be sure to check out the [FAQ](https://github.com/ethereumjs/testrpc/wiki/FAQ) and if you're still having issues and you're sure its a problem with `testrpc` please open an issue.

# USAGE

### Command Line

```Bash
$ testrpc <options>
```

Options:

* `-a` or `--accounts`: Specify the number of accounts to generate at startup.
* `-b` or `--blocktime`: Specify blocktime in seconds for automatic mining. Default is 0 and no auto-mining.
* `-d` or `--deterministic`: Generate deterministic addresses based on a pre-defined mnemonic.
* `-n` or `--secure`: Lock available accounts by default (good for third party transaction signing)
* `-m` or `--mnemonic`: Use a specific HD wallet mnemonic to generate initial addresses.
* `-p` or `--port`: Port number to listen on. Defaults to 8545.
* `-h` or `--hostname`: Hostname to listen on. Defaults to Node's `server.listen()` [default](https://nodejs.org/api/http.html#http_server_listen_port_hostname_backlog_callback).
* `-s` or `--seed`: Use arbitrary data to generate the HD wallet mnemonic to be used.
* `-g` or `--gasPrice`: Use a custom Gas Price (defaults to 20000000000)
* `-l` or `--gasLimit`: Use a custom Gas Limit (defaults to 0x47E7C4)
* `-f` or `--fork`: Fork from another currently running Ethereum client at a given block. Input should be the HTTP location and port of the other client, e.g. `http://localhost:8545`. You can optionally specify the block to fork from using an `@` sign: `http://localhost:8545@1599200`.
* `-i` or `--network-id`: Specify the network id the TestRPC will use to identify itself (defaults to the current time or the network id of the forked blockchain if configured)
* `--db`: Specify a path to a directory to save the chain database. If a database already exists, the TestRPC will initialize that chain instead of creating a new one.
* `--debug`: Output VM opcodes for debugging
* `--mem`: Output TestRPC memory usage statistics. This replaces normal output.

Special Options:

* `--account`: Specify `--account=...` (no 's') any number of times passing arbitrary private keys and their associated balances to generate initial addresses:

```
$ testrpc --account="<privatekey>,balance" [--account="<privatekey>,balance"]
```

Note that private keys are 64 characters long, and must be input as a 0x-prefixed hex string. Balance can either be input as an integer or 0x-prefixed hex value specifying the amount of wei in that account.

An HD wallet will not be created for you when using `--account`.

* `-u` or `--unlock`: Specify `--unlock ...` any number of times passing either an address or an account index to unlock specific accounts. When used in conjunction with `--secure`, `--unlock` will override the locked state of specified accounts.

```
$ testrpc --secure --unlock "0x1234..." --unlock "0xabcd..."
```

You can also specify a number, unlocking accounts by their index:

```
$ testrpc --secure -u 0 -u 1
```

This feature can also be used to impersonate accounts and unlock addresses you wouldn't otherwise have access to. When used with the `--fork` feature, you can use the TestRPC to make transactions as any address on the blockchain, which is very useful for testing and dynamic analysis.

### Library

As a Web3 provider:

```javascript
var TestRPC = require("ethereumjs-testrpc");
web3.setProvider(TestRPC.provider());
var Ganache = require("ganache-core");
web3.setProvider(Ganache.provider());
```

As a general http server:

```javascript
var TestRPC = require("ethereumjs-testrpc");
var server = TestRPC.server();
var Ganache = require("ganache-core");
var server = Ganache.server();
server.listen(port, function(err, blockchain) {...});
```

Both `.provider()` and `.server()` take a single object which allows you to specify behavior of the TestRPC. This parameter is optional. Available options are:
Both `.provider()` and `.server()` take a single object which allows you to specify behavior of the Ganache instance. This parameter is optional. Available options are:

* `"accounts"`: `Array` of `Object`'s. Each object should have a balance key with a hexadecimal value. The key `secretKey` can also be specified, which represents the account's private key. If no `secretKey`, the address is auto-generated with the given balance. If specified, the key is used to determine the account's address.
* `"debug"`: `boolean` - Output VM opcodes for debugging
* `"logger"`: `Object` - Object, like `console`, that implements a `log()` function.
* `"mnemonic"`: Use a specific HD wallet mnemonic to generate initial addresses.
* `"port"`: Port number to listen on when running as a server.
* `"seed"`: Use arbitrary data to generate the HD wallet mnemonic to be used.
* `"default_balance_ether"`: `number` - The default account balance, specified in ether.
* `"total_accounts"`: `number` - Number of accounts to generate at startup.
* `"fork"`: `string` - Same as `--fork` option above.
* `"fork"`: `string` or `object` - When a `string`, same as `--fork` option above. Can also be a Web3 Provider object, optionally used in conjunction with the `fork_block_number` option below.
* `"fork_block_number"`: `string` or `number` - Block number the provider should fork from, when the `fork` option is specified. If the `fork` option is specified as a string including the `@` sign and a block number, the block number in the `fork` parameter takes precedence.
* `"network_id"`: `integer` - Same as `--networkId` option above.
* `"time"`: `Date` - Date that the first block should start. Use this feature, along with the `evm_increaseTime` method to test time-dependent code.
* `"locked"`: `boolean` - whether or not accounts are locked by default.
* `"unlocked_accounts"`: `Array` - array of addresses or address indexes specifying which accounts should be unlocked.
* `"db_path"`: `String` - Specify a path to a directory to save the chain database. If a database already exists, the TestRPC will initialize that chain instead of creating a new one.
* `"db_path"`: `String` - Specify a path to a directory to save the chain database. If a database already exists, that chain will be initialized instead of creating a new one.
* `"db"`: `Object` - Specify an alternative database instance, for instance [MemDOWN](https://github.com/level/memdown).
* `"ws"`: Enable a websocket server. This is `true` by default.
* `"vmErrorsOnRPCResponse"`: Whether to report runtime errors from EVM code as RPC errors. This is `true` by default to replicate the error reporting behavior of previous versions of ganache.
* `"hdPath"`: The hierarchical deterministic path to use when generating accounts. Default: "m/44'/60'/0'/0/"

# IMPLEMENTED METHODS

The RPC methods currently implemented are:

* `bzz_hive` (stub)
* `bzz_info` (stub)
* `debug_traceTransaction`
* `eth_accounts`
* `eth_blockNumber`
* `eth_call`
Expand All @@ -140,16 +92,26 @@ The RPC methods currently implemented are:
* `eth_mining`
* `eth_newBlockFilter`
* `eth_newFilter` (includes log/event filters)
* `eth_protocolVersion`
* `eth_sendTransaction`
* `eth_sendRawTransaction`
* `eth_sign`
* `eth_subscribe` (only for websocket connections. "syncing" subscriptions are not yet supported)
* `eth_unsubscribe` (only for websocket connections. "syncing" subscriptions are not yet supported)
* `eth_syncing`
* `eth_uninstallFilter`
* `net_listening`
* `net_peerCount`
* `net_version`
* `miner_start`
* `miner_stop`
* `personal_listAccounts`
* `personal_lockAccount`
* `personal_newAccount`
* `personal_importRawKey`
* `personal_unlockAccount`
* `personal_sendTransaction`
* `shh_version`
* `rpc_modules`
* `web3_clientVersion`
* `web3_sha3`
Expand All @@ -165,28 +127,6 @@ There’s also special non-standard methods that aren’t included within the or

* `eth_compileSolidity`: If you'd like Solidity compilation in Javascript, please see the [solc-js project](https://github.com/ethereum/solc-js).

# Docker

The Simplest way to get started with the Docker image:

```Bash
docker run -d -p 8545:8545 ethereumjs/testrpc:latest
```

To pass options to testrpc through Docker simply add the arguments to
the run command:

```Bash
docker run -d -p 8545:8545 ethereumjs/testrpc:latest -a 10 --debug
```

To build the Docker container from source:

```Bash
git clone https://github.com/ethereumjs/testrpc.git && cd testrpc
docker build -t ethereumjs/testrpc .
```


# TESTING

Expand All @@ -197,4 +137,4 @@ $ npm test
```

# LICENSE
[MPL-2.0](https://tldrlegal.com/license/mozilla-public-license-2.0-(mpl-2))
[MIT](https://tldrlegal.com/license/mit-license)
66 changes: 66 additions & 0 deletions lib/block_tracker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// this replaces `eth-block-tracker` in the provider-engine, as that block tracker is meant to work with
// an external provider instance

const EventEmitter = require('events')
const BlockSerializer = require('./database/blockserializer')
var blockHelper = require('./utils/block_helper');
const to = require('./utils/to')

function GanacheBlockTracker(opts) {
opts = opts || {}
EventEmitter.apply(this)
if (!opts.blockchain) throw new Error('RpcBlockTracker - no blockchain specified.')
if (!opts.blockchain.on) throw new Error('RpcBlockTracker - blockchain is not an EventEmitter.')
this._blockchain = opts.blockchain
this.start = this.start.bind(this)
this.stop = this.stop.bind(this)
this.getTrackingBlock = this.getTrackingBlock.bind(this)
this.awaitCurrentBlock = this.awaitCurrentBlock.bind(this)
this._setCurrentBlock = this._setCurrentBlock.bind(this)
}

GanacheBlockTracker.prototype = Object.create(EventEmitter.prototype)
GanacheBlockTracker.prototype.constructor = GanacheBlockTracker

GanacheBlockTracker.prototype.getTrackingBlock = function() {
return this._currentBlock
}

GanacheBlockTracker.prototype.getCurrentBlock = function() {
return this._currentBlock
}

GanacheBlockTracker.prototype.awaitCurrentBlock = function() {
const self = this
// return if available
if (this._currentBlock) return this._currentBlock
// wait for "sync" event
return new Promise(resolve => this.once('block', resolve))
.then(() => self._currentBlock)
}

GanacheBlockTracker.prototype.start = function(opts = {}) {
this._blockchain.on('block', this._setCurrentBlock)
return Promise.resolve()
}

GanacheBlockTracker.prototype.stop = function() {
this._isRunning = false
this._blockchain.removeListener(_setCurrentBlock)
}

//
// private
//

GanacheBlockTracker.prototype._setCurrentBlock = function(newBlock) {
let block = blockHelper.toJSON(newBlock, true)
if (this._currentBlock && (this._currentBlock.hash === block.hash)) return
const oldBlock = this._currentBlock
this._currentBlock = block
this.emit('latest', block)
this.emit('sync', { block, oldBlock })
this.emit('block', block)
}

module.exports = GanacheBlockTracker
Loading

0 comments on commit ba4f4b3

Please sign in to comment.