Skip to content

Commit b1ef0a6

Browse files
authored
Merge pull request ethereumjs#540 from ethereumjs/istanbul-draft-eip1108-support
Istanbul Draft EIP-1108 Support
2 parents 5d4fa87 + adcfc76 commit b1ef0a6

File tree

8 files changed

+153
-3
lines changed

8 files changed

+153
-3
lines changed

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,31 @@ The VM currently supports the following hardfork rules:
1616
- `Byzantium`
1717
- `Constantinople`
1818
- `Petersburg` (default)
19+
- `Istanbul` (`DRAFT`)
1920

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

23+
##### Istanbul Harfork Support
24+
25+
With the `v4.0.0` release we are starting to add implementations of EIPs being
26+
candidates or accepted for inclusion within the `Istanbul` hardfork. You can
27+
activate a preliminary `Istanbul` VM by using the `istanbul` `hardfork` option
28+
flag.
29+
30+
Currently supported `Istanbul` EIPs:
31+
32+
- [EIP-1108](https://eips.ethereum.org/EIPS/eip-1803) (Candidate): `alt_bn128` Gas Cost Reductions, see PR [#540](https://github.com/ethereumjs/ethereumjs-vm/pull/540)
33+
34+
Note that this is highly experimental and solely meant for experimental purposes,
35+
since `Istanbul` scope is not yet finalized and most EIPs are still in a `DRAFT`
36+
state and likely subject to updates and changes.
37+
38+
A final `Istanbul` VM will be released along a major version bump to likely
39+
`v5.0.0` or `v6.0.0`.
40+
41+
Have a look at the corresponding issue to follow the discussion and current state on
42+
[Istanbul planning](https://github.com/ethereumjs/ethereumjs-vm/issues/501).
43+
2244
# INSTALL
2345

2446
`npm install ethereumjs-vm`

lib/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export default class VM extends AsyncEventEmitter {
6363
* Instantiates a new [[VM]] Object.
6464
* @param opts - Default values for the options are:
6565
* - `chain`: 'mainnet'
66-
* - `hardfork`: 'petersburg' [supported: 'byzantium', 'constantinople', 'petersburg' (will throw on unsupported)]
66+
* - `hardfork`: 'petersburg' [supported: 'byzantium', 'constantinople', 'petersburg', 'istanbul' (DRAFT) (will throw on unsupported)]
6767
* - `activatePrecompiles`: false
6868
* - `allowUnlimitedContractSize`: false [ONLY set to `true` during debugging]
6969
*/
@@ -83,7 +83,7 @@ export default class VM extends AsyncEventEmitter {
8383
} else {
8484
const chain = opts.chain ? opts.chain : 'mainnet'
8585
const hardfork = opts.hardfork ? opts.hardfork : 'petersburg'
86-
const supportedHardforks = ['byzantium', 'constantinople', 'petersburg']
86+
const supportedHardforks = ['byzantium', 'constantinople', 'petersburg', 'istanbul']
8787

8888
this._common = new Common(chain, hardfork, supportedHardforks)
8989
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
"ethereumjs-account": "^3.0.0",
5454
"ethereumjs-block": "~2.2.0",
5555
"ethereumjs-blockchain": "^3.4.0",
56-
"ethereumjs-common": "^1.1.0",
56+
"ethereumjs-common": "1.2.1",
5757
"ethereumjs-util": "^6.1.0",
5858
"fake-merkle-patricia-tree": "^1.0.1",
5959
"functional-red-black-tree": "^1.0.1",

tests/api/evm/precompiles/06-ecadd.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const BN = require('bn.js')
2+
const tape = require('tape')
3+
const Common = require('ethereumjs-common').default
4+
const util = require('ethereumjs-util')
5+
const VM = require('../../../../dist/index').default
6+
const { getPrecompile } = require('../../../../dist/evm/precompiles')
7+
8+
tape('Precompiles: ECADD', (t) => {
9+
t.test('ECADD', (st) => {
10+
const common = new Common('mainnet', 'petersburg')
11+
let vm = new VM({ common: common })
12+
let ECADD = getPrecompile('0000000000000000000000000000000000000006')
13+
14+
let result = ECADD({
15+
data: Buffer.alloc(0),
16+
gasLimit: new BN(0xffff),
17+
_common: common
18+
})
19+
st.deepEqual(result.gasUsed.toNumber(), 500, 'should use petersburg gas costs')
20+
st.end()
21+
})
22+
})

tests/api/evm/precompiles/07-ecmul.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const BN = require('bn.js')
2+
const tape = require('tape')
3+
const Common = require('ethereumjs-common').default
4+
const util = require('ethereumjs-util')
5+
const VM = require('../../../../dist/index').default
6+
const { getPrecompile } = require('../../../../dist/evm/precompiles')
7+
8+
tape('Precompiles: ECMUL', (t) => {
9+
t.test('ECMUL', (st) => {
10+
const common = new Common('mainnet', 'petersburg')
11+
let vm = new VM({ common: common })
12+
let ECMUL = getPrecompile('0000000000000000000000000000000000000007')
13+
14+
let result = ECMUL({
15+
data: Buffer.alloc(0),
16+
gasLimit: new BN(0xffff),
17+
_common: common
18+
})
19+
st.deepEqual(result.gasUsed.toNumber(), 40000, 'should use petersburg gas costs')
20+
st.end()
21+
})
22+
})
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const BN = require('bn.js')
2+
const tape = require('tape')
3+
const Common = require('ethereumjs-common').default
4+
const util = require('ethereumjs-util')
5+
const VM = require('../../../../dist/index').default
6+
const { getPrecompile } = require('../../../../dist/evm/precompiles')
7+
8+
tape('Precompiles: ECPAIRING', (t) => {
9+
t.test('ECPAIRING', (st) => {
10+
const common = new Common('mainnet', 'petersburg')
11+
let vm = new VM({ common: common })
12+
let ECPAIRING = getPrecompile('0000000000000000000000000000000000000008')
13+
14+
let result = ECPAIRING({
15+
data: Buffer.from('00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa', 'hex'),
16+
gasLimit: new BN(0xffffff),
17+
_common: common
18+
})
19+
st.deepEqual(result.gasUsed.toNumber(), 260000, 'should use petersburg gas costs (k ^= 2 pairings)')
20+
st.end()
21+
})
22+
})

tests/api/istanbul/eip-1108.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
const BN = require('bn.js')
2+
const tape = require('tape')
3+
const Common = require('ethereumjs-common').default
4+
const util = require('ethereumjs-util')
5+
const VM = require('../../../dist/index').default
6+
const { getPrecompile } = require('../../../dist/evm/precompiles')
7+
8+
tape('Istanbul: EIP-1108 tests', (t) => {
9+
t.test('ECADD', (st) => {
10+
const common = new Common('mainnet', 'istanbul')
11+
let vm = new VM({ common: common })
12+
let ECADD = getPrecompile('0000000000000000000000000000000000000006')
13+
14+
let result = ECADD({
15+
data: Buffer.alloc(0),
16+
gasLimit: new BN(0xffff),
17+
_common: common
18+
})
19+
st.deepEqual(result.gasUsed.toNumber(), 150, 'should use istanbul gas costs')
20+
st.end()
21+
})
22+
23+
t.test('ECMUL', (st) => {
24+
const common = new Common('mainnet', 'istanbul')
25+
let vm = new VM({ common: common })
26+
let ECMUL = getPrecompile('0000000000000000000000000000000000000007')
27+
28+
let result = ECMUL({
29+
data: Buffer.alloc(0),
30+
gasLimit: new BN(0xffff),
31+
_common: common
32+
})
33+
st.deepEqual(result.gasUsed.toNumber(), 6000, 'should use istanbul gas costs')
34+
st.end()
35+
})
36+
37+
t.test('ECPAIRING', (st) => {
38+
const common = new Common('mainnet', 'istanbul')
39+
let vm = new VM({ common: common })
40+
let ECPAIRING = getPrecompile('0000000000000000000000000000000000000008')
41+
42+
let result = ECPAIRING({
43+
data: Buffer.from('00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa', 'hex'),
44+
gasLimit: new BN(0xffffff),
45+
_common: common
46+
})
47+
st.deepEqual(result.gasUsed.toNumber(), 113000, 'should use petersburg gas costs (k ^= 2 pairings)')
48+
st.end()
49+
})
50+
})

tests/api/istanbul/index.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
const tape = require('tape')
2+
const util = require('ethereumjs-util')
3+
const VM = require('../../../dist/index').default
4+
5+
tape('General Istanbul VM tests', (t) => {
6+
t.test('should accept istanbul harfork option', (st) => {
7+
const vm = new VM({ hardfork: 'istanbul' })
8+
st.ok(vm.stateManager)
9+
st.deepEqual(vm.stateManager._trie.root, util.KECCAK256_RLP, 'it has default trie')
10+
st.end()
11+
})
12+
})

0 commit comments

Comments
 (0)