Skip to content

Commit

Permalink
VM: Replace BN.js with bigints, Util helpers (#1671)
Browse files Browse the repository at this point in the history
* Replace BN.js with bigints in VM

* Fix byteLength computation in EXP handler

* Fix toTwos helper

* Compute TWO_POWE256 using math instead of hex

* Update packages/util/src/constants.ts

Co-authored-by: Ryan Ghods <[email protected]>

* Remove unused variable

* Fix exponent byte length calc

* Fix exp overflow

* Fix precompile bigint conversions

* Fix more bigint conversions

* Fix EXP opcode handler

* Fix logic bug in signextend

* vm/gas: fix EXTCODECOPY gas

* vm/gas: fix sha256 gas

* vm/gas: sha256 const -> let

* vm: lint

* vm/logic: fix sdiv/smod and fromTwos/toTwos

* vm/logic: fix SIGNEXTEND

* vm/logic: fix CALLDATALOAD padding

* vm/logic: remove weird comment

* Fix SAR opcode handler

* Use bufferToBigInt in Push opcode handler

* use bufferToBigInt everywhere

* Fix missing bufferToBigInt import

* Check for edge case in expmod

* Ignore prettier

* Update browser tsconfig to es2020 lib

* Remove dup ES2020 targets

* attempt to dedupe "target" and "lib" tsconfig values

* Update karma config to target es2020 in parser

* Various test fixes

* Lint and BN fixes

* Add bigint helpers to util

* lint fixes

* various bigint helper additions

* Lint fixes

* Fix bnToBigInt

* Lint/test fixes

* Switch Xn to BigInt(X)

* lint

* lint

* More Xn to BigInt(X) moves

Co-authored-by: Ryan Ghods <[email protected]>
Co-authored-by: Jochem Brouwer <[email protected]>
Co-authored-by: Jochem Brouwer <[email protected]>
  • Loading branch information
4 people authored and g11tech committed Jun 1, 2022
1 parent c01b8b1 commit 7d04be9
Show file tree
Hide file tree
Showing 99 changed files with 1,238 additions and 1,083 deletions.
2 changes: 1 addition & 1 deletion config/eslint.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module.exports = {
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint', 'implicit-dependencies', 'prettier'],
env: {
es6: true,
es2020: true,
node: true,
},
ignorePatterns: [
Expand Down
3 changes: 1 addition & 2 deletions config/tsconfig.browser.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"target": "es5",
"lib": ["dom", "es5"]
"lib": ["dom", "ES2020"]
}
}
4 changes: 2 additions & 2 deletions config/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"resolveJsonModule": true,
"downlevelIteration": true,
"strict": true,
"target": "ES2017",
"lib": ["es2018"]
"target": "es2020",
"lib": ["ES2020"]
}
}
3 changes: 3 additions & 0 deletions packages/block/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ module.exports = function(config) {
tsconfig: './tsconfig.json',
bundlerOptions: {
entrypoints: /\.spec\.ts$/,
acornOptions: {
ecmaVersion: 11
}
},
},
concurrency: 1,
Expand Down
3 changes: 3 additions & 0 deletions packages/blockchain/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ module.exports = function(config) {
tsconfig: './tsconfig.json',
bundlerOptions: {
entrypoints: /\.spec\.ts$/,
acornOptions: {
ecmaVersion: 11
}
},
},
concurrency: 1,
Expand Down
3 changes: 3 additions & 0 deletions packages/client/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ module.exports = function (config) {
karmaTypescriptConfig: {
bundlerOptions: {
entrypoints: /\.spec\.ts$/,
acornOptions: {
ecmaVersion: 11
},
resolve: {
alias: {
// Hotfix for `multiformats` client browser build error in Node 16, #1346, 2021-07-12
Expand Down
6 changes: 4 additions & 2 deletions packages/client/lib/miner/miner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,11 +271,13 @@ export class Miner {
await blockBuilder.addTransaction(txs[index])
} catch (error: any) {
if (error.message === 'tx has a higher gas limit than the remaining gas in the block') {
if (blockBuilder.gasUsed.gt(gasLimit.subn(21000))) {
if (blockBuilder.gasUsed > BigInt(gasLimit.subn(21000).toString(10))) {
// If block has less than 21000 gas remaining, consider it full
blockFull = true
this.config.logger.info(
`Miner: Assembled block full (gasLeft: ${gasLimit.sub(blockBuilder.gasUsed)})`
`Miner: Assembled block full (gasLeft: ${gasLimit.sub(
new BN(blockBuilder.gasUsed.toString(10))
)})`
)
}
} else {
Expand Down
4 changes: 2 additions & 2 deletions packages/client/lib/rpc/modules/eth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ export class Eth {
skipBalance: true,
skipBlockGasLimitValidation: true,
})
return bnToHex(gasUsed)
return `0x${gasUsed.toString(16)}`
} catch (error: any) {
throw {
code: INTERNAL_ERROR,
Expand Down Expand Up @@ -763,7 +763,7 @@ export class Eth {
const { gasUsed, createdAddress } = runBlockResult.results[txIndex]
return jsonRpcReceipt(
receipt,
gasUsed,
new BN(gasUsed.toString(10)),
effectiveGasPrice,
block,
tx,
Expand Down
2 changes: 1 addition & 1 deletion packages/client/test/rpc/eth/estimateGas.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ tape(`${method}: call with valid arguments`, async (t) => {
const req = params(method, [{ ...estimateTxData, gas: estimateTxData.gasLimit }, 'latest'])
const expectRes = (res: any) => {
const msg = 'should return the correct gas estimate'
t.equal(res.body.result, bnToHex(gasUsed), msg)
t.equal(res.body.result, '0x' + gasUsed.toString(16), msg)
}
await baseRequest(t, server, req, 200, expectRes)
})
Expand Down
2 changes: 1 addition & 1 deletion packages/client/test/rpc/eth/getBalance.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ tape(`${method}: ensure balance deducts after a tx`, async (t) => {
const { amountSpent } = result.results[0]

// verify balance is genesis amount minus amountSpent
const expectedNewBalance = genesisBalance.sub(amountSpent)
const expectedNewBalance = genesisBalance.sub(new BN(amountSpent.toString(10)))
req = params(method, [address.toString(), 'latest'])
expectRes = (res: any) => {
const msg = 'should return the correct balance after a tx'
Expand Down
1 change: 0 additions & 1 deletion packages/client/tsconfig.browser.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"include": ["browser/index.ts"],
"exclude": ["lib/index.js"],
"compilerOptions": {
"target": "ES2017",
"outDir": "dist.browser",
"typeRoots": ["node_modules/@types", "lib/@types"],
}
Expand Down
1 change: 0 additions & 1 deletion packages/client/tsconfig.prod.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"include": ["bin", "lib"],
"compilerOptions": {
"outDir": "dist",
"lib": ["es2018", "dom"],
"typeRoots": ["node_modules/@types", "lib/@types"],
},
"references": [
Expand Down
3 changes: 3 additions & 0 deletions packages/common/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ module.exports = function(config) {
tsconfig: './tsconfig.json',
bundlerOptions: {
entrypoints: /\.spec\.ts$/,
acornOptions: {
ecmaVersion: 11
}
},
},
concurrency: 1,
Expand Down
1 change: 0 additions & 1 deletion packages/common/tsconfig.prod.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist",
"lib": ["dom"],
"composite": true
},
"include": ["src/**/*.ts", "src/**/*.json"],
Expand Down
3 changes: 3 additions & 0 deletions packages/trie/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ module.exports = function (config) {
tsconfig: './tsconfig.json',
bundlerOptions: {
entrypoints: /\.spec\.ts$/,
acornOptions: {
ecmaVersion: 11
}
},
},
colors: true,
Expand Down
5 changes: 2 additions & 3 deletions packages/trie/tsconfig.browser.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
{
"extends": "./tsconfig.prod.json",
"extends": "../../config/tsconfig.browser.json",
"include": ["src/**/*.ts"],
"compilerOptions": {
"outDir": "./dist.browser",
"target": "es5",
"lib": ["dom", "es5"]
}
}

1 change: 0 additions & 1 deletion packages/trie/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"extends": "../../config/tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"lib": ["dom"],
},
"include": ["src/**/*.ts", "test/*.spec.ts"]
}
Expand Down
2 changes: 0 additions & 2 deletions packages/trie/tsconfig.prod.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist",
"target": "ES2017",
"lib": ["dom"],
"composite": true
},
"include": ["src/**/*.ts"],
Expand Down
3 changes: 3 additions & 0 deletions packages/tx/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ module.exports = function (config) {
tsconfig: './tsconfig.json',
bundlerOptions: {
entrypoints: /\.spec\.ts$/,
acornOptions: {
ecmaVersion: 11
}
},
},
browsers: ['FirefoxHeadless', 'ChromeHeadless'],
Expand Down
18 changes: 18 additions & 0 deletions packages/util/src/bytes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -332,3 +332,21 @@ export function bufArrToArr(arr: Buffer | NestedBufferArray): Uint8Array | Neste
}
return arr.map((a) => bufArrToArr(a))
}

/**
* Converts a {@link Buffer} to a {@link bigint}`
*/
export function bufferToBigInt(buf: Buffer) {
const hex = bufferToHex(buf)
if (hex === '0x') {
return BigInt(0)
}
return BigInt(hex)
}

/**
* Converts a {@link bigint} to a {@link Buffer}
*/
export function bigIntToBuffer(num: bigint) {
return toBuffer('0x' + num.toString(16))
}
12 changes: 12 additions & 0 deletions packages/util/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,26 @@ export const MAX_INTEGER = new BN(
16
)

/**
* The max integer that the evm can handle (2^256-1) as a bigint
*/
export const MAX_INTEGER_BIGINT = BigInt(2) ** BigInt(256) - BigInt(1)

/**
* 2^256
*
* @deprecated bn.js constants are deprecated, please use the newly introduced bigint constants
*/
export const TWO_POW256 = new BN(
'10000000000000000000000000000000000000000000000000000000000000000',
16
)

/**
* 2^256
*/
export const TWO_POW256_BIGINT = BigInt(2) ** BigInt(256)

/**
* Keccak-256 hash of null
*/
Expand Down
12 changes: 12 additions & 0 deletions packages/util/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,15 @@ export function toType<T extends TypeOutput>(
return `0x${output.toString('hex')}` as TypeOutputReturnType[T]
}
}

export const bnToBigInt = (bn: BN) => {
return BigInt(new BN(bn).toString(10))
}

export const bigIntToBN = (num: bigint) => {
return new BN(num.toString(10))
}

export const bigIntToHex = (num: bigint) => {
return '0x' + num.toString(16)
}
14 changes: 14 additions & 0 deletions packages/util/test/bytes.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import {
intToBuffer,
intToHex,
validateNoLeadingZeroes,
bufferToBigInt,
bigIntToBuffer,
} from '../src'

tape('zeros function', function (t) {
Expand Down Expand Up @@ -443,3 +445,15 @@ tape('bufArrToArr', function (st) {
st.deepEqual(bufArrToArr(bufArr), uint8Arr)
st.end()
})

tape('bufferToBigInt', (st) => {
const buf = toBuffer('0x123')
st.equal(BigInt(0x123), bufferToBigInt(buf))
st.end()
})

tape('bigIntToBuffer', (st) => {
const num = BigInt(0x123)
st.deepEqual(toBuffer('0x123'), bigIntToBuffer(num))
st.end()
})
6 changes: 6 additions & 0 deletions packages/util/test/constants.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
KECCAK256_RLP_ARRAY,
KECCAK256_RLP_S,
KECCAK256_RLP,
TWO_POW256_BIGINT,
} from '../src'

tape('constants', function (t) {
Expand All @@ -22,6 +23,11 @@ tape('constants', function (t) {
'10000000000000000000000000000000000000000000000000000000000000000'
)

st.equal(
TWO_POW256_BIGINT.toString(16),
'10000000000000000000000000000000000000000000000000000000000000000'
)

st.equal(KECCAK256_NULL_S, 'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470')

st.equal(
Expand Down
18 changes: 18 additions & 0 deletions packages/util/test/types.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import {
bnToHex,
bnToUnpaddedBuffer,
toBuffer,
bnToBigInt,
bigIntToBN,
bigIntToHex,
} from '../src'

tape('toType', function (t) {
Expand Down Expand Up @@ -142,3 +145,18 @@ tape('bnToUnpaddedBuffer', function (t) {
st.end()
})
})

tape('bnToBigInt', (st) => {
st.equal(bnToBigInt(new BN(1)), BigInt(1))
st.end()
})

tape('bigIntToBN', (st) => {
st.ok(bigIntToBN(BigInt(1)).eq(new BN(1)))
st.end()
})

tape('bigIntToHex', (st) => {
st.equal(bigIntToHex(BigInt(1)), '0x1')
st.end()
})
5 changes: 2 additions & 3 deletions packages/util/tsconfig.browser.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
{
"extends": "./tsconfig.prod.json",
"extends": "../../config/tsconfig.browser.json",
"include": ["src/**/*.ts"],
"compilerOptions": {
"outDir": "./dist.browser",
"target": "es5",
"lib": ["dom", "es5"]
}
}

2 changes: 1 addition & 1 deletion packages/util/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"extends": "../../config/tsconfig.json",
"include": ["src/**/*.ts", "test/**/*.ts"]
"include": ["src/**/*.ts", "test/**/*.ts"],
}
2 changes: 1 addition & 1 deletion packages/util/tsconfig.prod.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist",
"composite": true
"composite": true,
},
"include": ["src/**/*.ts"]
}
4 changes: 2 additions & 2 deletions packages/vm/benchmarks/util.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Account, Address, toBuffer, bufferToInt, BN } from 'ethereumjs-util'
import { Account, Address, toBuffer, bufferToInt, BN, bnToBigInt } from 'ethereumjs-util'
import Common from '@ethereumjs/common'
import { Block } from '@ethereumjs/block'
import { StateManager, DefaultStateManager } from '../dist/state'
Expand Down Expand Up @@ -100,7 +100,7 @@ export const verifyResult = (block: Block, result: RunBlockResult) => {
if (!result.logsBloom.equals(block.header.logsBloom)) {
throw new Error('invalid logsBloom')
}
if (!block.header.gasUsed.eq(result.gasUsed)) {
if (!(bnToBigInt(block.header.gasUsed) === result.gasUsed)) {
throw new Error('invalid gasUsed')
}
}
3 changes: 3 additions & 0 deletions packages/vm/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ module.exports = function (config) {
tsconfig: './tsconfig.json',
bundlerOptions: {
entrypoints: /\.spec\.ts$/,
acornOptions: {
ecmaVersion: 11
}
},
},

Expand Down
Loading

0 comments on commit 7d04be9

Please sign in to comment.