Skip to content

Commit

Permalink
Merge branch 'master' into dao-support
Browse files Browse the repository at this point in the history
  • Loading branch information
holgerd77 authored Aug 27, 2020
2 parents c035e03 + 9d1c766 commit 52a6017
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 40 deletions.
17 changes: 2 additions & 15 deletions .github/workflows/vm-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -135,23 +135,12 @@ jobs:
- run: npm run benchmarks -- 10 | tee output.txt
working-directory: ${{ env.cwd }}

- name: Set auto-push for benchmarks to true if on master
id: auto_push
run: |
if [$REF == 'refs/heads/master']
then
echo "::set-output name=auto_push::true"
else
echo "::set-output name=auto_push::false"
fi
env:
REF: ${{ github.ref }}

# Run git stash in case github-action-benchmark has trouble switching to gh-pages branch due to differing package-locks
- run: git stash

- name: Compare benchmarks
uses: rhysd/github-action-benchmark@v1
if: github.ref == 'refs/heads/master'
with:
tool: 'benchmarkjs'
# Where the output from the benchmark tool is stored
Expand All @@ -163,10 +152,8 @@ jobs:
# GitHub API token to make a commit comment
github-token: ${{ secrets.GITHUB_TOKEN }}
# Push and deploy to GitHub pages branch automatically (if on master)
auto-push: ${{ steps.auto_push.outputs.auto_push }}
auto-push: 'true'

# Re-apply git stash to prepare for saving back to cache.
# Avoids exit code 1 by checking if there are changes to be stashed first
- run: STASH_LIST=`git stash list` && [ ! -z $STASH_LIST ] && git stash apply || echo "No files to stash-apply. Skipping…"


60 changes: 60 additions & 0 deletions packages/vm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,66 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
(modification: no type change headlines) and this project adheres to
[Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [5.0.0] - [UNRELEASED]

This major release implements EIP-2315 (subroutines) which is part of the `Berlin`
fork and adds hardfork support for older hard forks.

**Additions**

- Add EIP-2315 (subroutines),
PR [#754](https://github.com/ethereumjs/ethereumjs-vm/pull/754)
- Add StateManager interface,
PR [#763](https://github.com/ethereumjs/ethereumjs-vm/pull/763)
- Add Frontier hardfork support,
PR [#828](https://github.com/ethereumjs/ethereumjs-vm/pull/828)
- Add Homestead hardfork support,
PR [#815](https://github.com/ethereumjs/ethereumjs-vm/pull/815)
- Add Spurious Dragon hardfork support,
PR [#791](https://github.com/ethereumjs/ethereumjs-vm/pull/791)
- Add Tangerine Whistle hardfork support,
PR [#807](https://github.com/ethereumjs/ethereumjs-vm/pull/807)

**Changes**

- Update to MPT v4, move `Account` trie-related operations to `StateManager`,
PR [#787](https://github.com/ethereumjs/ethereumjs-vm/pull/787)
- Group opcodes based upon hardfork,
PR [#798](https://github.com/ethereumjs/ethereumjs-vm/pull/798)
- Group precompiles based upon hardfork,
PR [#783](https://github.com/ethereumjs/ethereumjs-vm/pull/783)

**Bug Fixes**

- Fix `activatePrecompiles`,
PR [#797](https://github.com/ethereumjs/ethereumjs-vm/pull/797)

## [4.2.0] - 2020-05-06

**Additions**

- Add `codeAddress` to VMs `step` event,
PR [#651](https://github.com/ethereumjs/ethereumjs-vm/pull/651)
- Support for `skipNonce` and `skipBalance` tx options in `runBlock`,
PR [#663](https://github.com/ethereumjs/ethereumjs-vm/pull/663)
- Add `init()` method to prevent race conditions,
PR [#665](https://github.com/ethereumjs/ethereumjs-vm/pull/665)

**Removals**

- Remove `PStateManager` (`StateManager` now uses Promises by default),
PR [#719](https://github.com/ethereumjs/ethereumjs-vm/pull/719)

**Bug Fixes**

- Explicitly duplicate EVMs stack items to ensure these do not get accidentally modified interally,
PR [#733](https://github.com/ethereumjs/ethereumjs-vm/pull/733)

**Other changes**

- Refactor opcodes,
PR [#664](https://github.com/ethereumjs/ethereumjs-vm/pull/664)

## [4.1.3] - 2020-01-09

This release fixes a critical bug preventing the `MuirGlacier` release `4.1.2`
Expand Down
6 changes: 4 additions & 2 deletions packages/vm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@ Implements Ethereum's VM in Javascript.

The VM currently supports the following hardfork rules:

- `Chainstart` (a.k.a. Frontier) (v5, UNRELEASED)
- `Homestead` (v5, UNRELEASED)
- `TangerineWhistle` (v5, UNRELEASED)
- `SpuriousDragon` (v5, UNRELEASED)
- `Byzantium`
- `Constantinople`
- `Petersburg` (default)
- `Istanbul`
- `MuirGlacier` (only `mainnet` and `ropsten`)

If you are still looking for a [Spurious Dragon](https://eips.ethereum.org/EIPS/eip-607) compatible version of this library install the latest of the `2.2.x` series (see [Changelog](./CHANGELOG.md)).

##### MuirGlacier Hardfork Support

An Ethereum test suite compliant `MuirGlacier` HF implementation is available
Expand Down
3 changes: 2 additions & 1 deletion packages/vm/lib/evm/interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export interface InterpreterStep {
pc: number
depth: number
address: Buffer
memory: number[]
memory: Buffer
memoryWordCount: BN
opcode: {
name: string
Expand Down Expand Up @@ -204,6 +204,7 @@ export default class Interpreter {
* @property {Buffer} memory the memory of the VM as a `buffer`
* @property {BN} memoryWordCount current size of memory in words
* @property {StateManager} stateManager a [`StateManager`](stateManager.md) instance (Beta API)
* @property {Buffer} codeAddress the address of the code which is currently being ran (this differs from `address` in a `DELEGATECALL` and `CALLCODE` call)
*/
return this._vm._emit('step', eventObj)
}
Expand Down
6 changes: 3 additions & 3 deletions packages/vm/lib/evm/memory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import * as assert from 'assert'
* for the ethereum virtual machine.
*/
export default class Memory {
_store: number[]
_store: Buffer

constructor() {
this._store = []
this._store = Buffer.alloc(0)
}

/**
Expand All @@ -23,7 +23,7 @@ export default class Memory {
const newSize = ceil(offset + size, 32)
const sizeDiff = newSize - this._store.length
if (sizeDiff > 0) {
this._store = this._store.concat(new Array(sizeDiff).fill(0))
this._store = Buffer.concat([this._store, Buffer.alloc(sizeDiff)])
}
}

Expand Down
12 changes: 6 additions & 6 deletions packages/vm/lib/evm/opFns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@ export const handlers: { [k: string]: OpHandler } = {
new BN(runState._common.param('gasPrices', 'sha3Word')).imul(divCeil(length, new BN(32))),
)
let gasLimit = new BN(runState.eei.getGasLeft())
gasLimit = maxCallGas(gasLimit, runState.eei.getGasLeft(), runState) // CREATE2 is only available after TW (Constantinople introduced this opcode)
gasLimit = maxCallGas(gasLimit, runState.eei.getGasLeft(), runState) // CREATE2 is only available after TangerineWhistle (Constantinople introduced this opcode)

let data = Buffer.alloc(0)
if (!length.isZero()) {
Expand Down Expand Up @@ -712,7 +712,7 @@ export const handlers: { [k: string]: OpHandler } = {
}

gasLimit = maxCallGas(gasLimit, runState.eei.getGasLeft(), runState)
// note that TW or later this cannot happen (it could have ran out of gas prior to getting here though)
// note that TangerineWhistle or later this cannot happen (it could have ran out of gas prior to getting here though)
if (gasLimit.gt(runState.eei.getGasLeft())) {
trap(ERROR.OUT_OF_GAS)
}
Expand Down Expand Up @@ -746,7 +746,7 @@ export const handlers: { [k: string]: OpHandler } = {
runState.eei.useGas(new BN(runState._common.param('gasPrices', 'callValueTransfer')))
}
gasLimit = maxCallGas(gasLimit, runState.eei.getGasLeft(), runState)
// note that TW or later this cannot happen (it could have ran out of gas prior to getting here though)
// note that TangerineWhistle or later this cannot happen (it could have ran out of gas prior to getting here though)
if (gasLimit.gt(runState.eei.getGasLeft())) {
trap(ERROR.OUT_OF_GAS)
}
Expand Down Expand Up @@ -774,7 +774,7 @@ export const handlers: { [k: string]: OpHandler } = {
subMemUsage(runState, inOffset, inLength)
subMemUsage(runState, outOffset, outLength)
gasLimit = maxCallGas(gasLimit, runState.eei.getGasLeft(), runState)
// note that TW or later this cannot happen (it could have ran out of gas prior to getting here though)
// note that TangerineWhistle or later this cannot happen (it could have ran out of gas prior to getting here though)
if (gasLimit.gt(runState.eei.getGasLeft())) {
trap(ERROR.OUT_OF_GAS)
}
Expand All @@ -796,7 +796,7 @@ export const handlers: { [k: string]: OpHandler } = {

subMemUsage(runState, inOffset, inLength)
subMemUsage(runState, outOffset, outLength)
gasLimit = maxCallGas(gasLimit, runState.eei.getGasLeft(), runState) // we set TW or later to true here, as STATICCALL was available from Byzantium (which is after TW)
gasLimit = maxCallGas(gasLimit, runState.eei.getGasLeft(), runState) // we set TangerineWhistle or later to true here, as STATICCALL was available from Byzantium (which is after TangerineWhistle)

let data = Buffer.alloc(0)
if (!inLength.isZero()) {
Expand Down Expand Up @@ -934,7 +934,7 @@ function jumpIsValid(runState: RunState, dest: number): boolean {
}

// returns the max call gas which we want to use for the gas limit
// note that pre-TW there was no hard limit. if you tried sending more gas, your CALLs (or equivalent) went OOG
// note that pre-TangerineWhistle there was no hard limit. if you tried sending more gas, your CALLs (or equivalent) went OOG
//

/**
Expand Down
8 changes: 7 additions & 1 deletion packages/vm/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ export default class VM extends AsyncEventEmitter {
* reverted if an exception is raised. If it's `false`, it won't revert if the block's header is
* invalid. If an error is thrown from an event handler, the state may or may not be reverted.
*
* @param opts - Default values for options:
* @param {RunBlockOpts} opts - Default values for options:
* - `generate`: false
*/
async runBlock(opts: RunBlockOpts): Promise<RunBlockResult> {
Expand All @@ -207,6 +207,8 @@ export default class VM extends AsyncEventEmitter {
* This method modifies the state. If an error is thrown, the modifications are reverted, except
* when the error is thrown from an event handler. In the latter case the state may or may not be
* reverted.
*
* @param {RunTxOpts} opts
*/
async runTx(opts: RunTxOpts): Promise<RunTxResult> {
await this.init()
Expand All @@ -217,6 +219,8 @@ export default class VM extends AsyncEventEmitter {
* runs a call (or create) operation.
*
* This method modifies the state.
*
* @param {RunCallOpts} opts
*/
async runCall(opts: RunCallOpts): Promise<EVMResult> {
await this.init()
Expand All @@ -227,6 +231,8 @@ export default class VM extends AsyncEventEmitter {
* Runs EVM code.
*
* This method modifies the state.
*
* @param {RunCodeOpts} opts
*/
async runCode(opts: RunCodeOpts): Promise<ExecResult> {
await this.init()
Expand Down
19 changes: 10 additions & 9 deletions packages/vm/lib/runBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,17 @@ export interface RunBlockOpts {
*/
root?: Buffer
/**
* Whether to generate the stateRoot. If false `runBlock` will check the
* stateRoot of the block against the Trie
* Whether to generate the stateRoot. If `true` `runBlock` will check the
* `stateRoot` of the block against the current Trie, check the `receiptsTrie`,
* the `gasUsed` and the `logsBloom` after running. If any does not match,
* `runBlock` throws.
* Defaults to `false`.
*/
generate?: boolean
/**
* If true, will skip block validation
* If true, will skip "Block validation":
* Block validation validates the header (with respect to the blockchain),
* the transactions, the transaction trie and the uncle hash.
*/
skipBlockValidation?: boolean
/**
Expand Down Expand Up @@ -195,7 +200,7 @@ export default async function runBlock(this: VM, opts: RunBlockOpts): Promise<Ru
* block itself. It computes the block rewards and puts
* them on state (but doesn't persist the changes).
* @param {Block} block
* @param {Boolean} [skipBlockValidation=false]
* @param {RunBlockOpts} opts
*/
async function applyBlock(this: VM, block: any, opts: RunBlockOpts) {
// Validate block
Expand All @@ -218,6 +223,7 @@ async function applyBlock(this: VM, block: any, opts: RunBlockOpts) {
* as well as gas usage and some relevant data. This method is
* side-effect free (it doesn't modify the block nor the state).
* @param {Block} block
* @param {RunBlockOpts} opts
*/
async function applyTransactions(this: VM, block: any, opts: RunBlockOpts) {
const bloom = new Bloom()
Expand Down Expand Up @@ -265,11 +271,6 @@ async function applyTransactions(this: VM, block: any, opts: RunBlockOpts) {
...abstractTxReceipt,
} as PostByzantiumTxReceipt
} else {
// This is just using a dummy place holder for the state root right now.
// Giving the correct intermediary state root would need a too depp intervention
// into the current checkpointing mechanism which hasn't been considered
// to be worth it on a HF backport, 2020-06-26

const stateRoot = await this.stateManager.getStateRoot(true)
txReceipt = {
stateRoot: stateRoot,
Expand Down
6 changes: 3 additions & 3 deletions packages/vm/tests/api/evm/memory.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ tape('Memory', t => {
})

t.test('should return zeros from empty memory', st => {
st.deepEqual(m.read(0, 3), Buffer.from([0, 0, 0]))
st.ok(m.read(0, 3).equals(Buffer.from([0, 0, 0])))
st.end()
})

Expand All @@ -21,7 +21,7 @@ tape('Memory', t => {
})

t.test('should return zeros before writing', st => {
st.deepEqual(m.read(0, 2), Buffer.from([0, 0]))
st.ok(m.read(0, 2).equals(Buffer.from([0, 0])))
st.end()
})

Expand All @@ -32,7 +32,7 @@ tape('Memory', t => {

t.test('should write value', st => {
m.write(29, 3, Buffer.from([1, 2, 3]))
st.deepEqual(m.read(29, 5), Buffer.from([1, 2, 3, 0, 0]))
st.ok(m.read(29, 5).equals(Buffer.from([1, 2, 3, 0, 0])))
st.end()
})

Expand Down

1 comment on commit 52a6017

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: 52a6017 Previous: 7e47bb5 Ratio
Block 9422905 1982 ops/sec (±2.79%) 1883 ops/sec (±3.94%) 0.95
Block 9422906 1839 ops/sec (±9.95%) 1904 ops/sec (±6.44%) 1.04
Block 9422907 2015 ops/sec (±1.45%) 1955 ops/sec (±1.10%) 0.97
Block 9422908 1961 ops/sec (±7.34%) 1707 ops/sec (±9.97%) 0.87
Block 9422909 1738 ops/sec (±11.25%) 1871 ops/sec (±1.07%) 1.08
Block 9422910 1918 ops/sec (±1.86%) 1863 ops/sec (±0.66%) 0.97
Block 9422911 1805 ops/sec (±1.21%) 1840 ops/sec (±1.12%) 1.02
Block 9422912 1895 ops/sec (±1.76%) 1812 ops/sec (±0.78%) 0.96
Block 9422913 1323 ops/sec (±16.91%) 1356 ops/sec (±14.22%) 1.02
Block 9422914 1842 ops/sec (±2.19%) 1701 ops/sec (±5.92%) 0.92

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.