Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

ethereumjs-vm

Package Overview
Dependencies
Maintainers
3
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ethereumjs-vm - npm Package Compare versions

Comparing version 2.3.5 to 2.4.0

47

CHANGELOG.md

@@ -8,2 +8,49 @@ # Changelog

## [2.4.0] - 2018-07-27
With the ``2.4.x`` release series we now start to gradually add ``Constantinople`` features with the
bitwise shifting instructions from [EIP 145](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md)
making the start being introduced in the ``v2.4.0`` release.
Since both the scope of the ``Constantinople`` hardfork as well as the state of at least some of the EIPs
to be included are not yet finalized, this is only meant for ``EXPERIMENTAL`` purposes, e.g. for developer
tools to give users early access and make themself familiar with dedicated features.
Once scope and EIPs from ``Constantinople`` are final we will target a ``v2.5.0`` release which will officially
introduce ``Constantinople`` support with all the changes bundled together.
Note that from this release on we also introduce new ``chain`` (default: ``mainnet``) and ``hardfork``
(default: ``byzantium``) initialization parameters, which make use of our new [ethereumjs-common](https://github.com/ethereumjs/ethereumjs-common) library and in the future will allow
for parallel hardfork support from ``Byzantium`` onwards.
Since ``hardfork`` default might be changed or dropped in future releases, you might want to explicitly
set this to ``byzantium`` on your next update to avoid future unexpected behavior.
All the changes from this release:
**FEATURES/FUNCTIONALITY**
- Improved chain and fork support, see PR [#304](https://github.com/ethereumjs/ethereumjs-vm/pull/304)
- Support for the ``Constantinople`` bitwise shifiting instructions ``SHL``, ``SHR`` and ``SAR``, see PR [#251](https://github.com/ethereumjs/ethereumjs-vm/pull/251)
- New ``newContract`` event which can be used to do interrupting tasks on contract/address creation, see PR [#306](https://github.com/ethereumjs/ethereumjs-vm/pull/306)
- Alignment of behavior of bloom filter hashing to go along with mainnet compatible clients *BREAKING*, see PR [#295](https://github.com/ethereumjs/ethereumjs-vm/pull/295)
**UPDATES/TESTING**
- Usage of the latest ``rustbn.js`` API, see PR [#312](https://github.com/ethereumjs/ethereumjs-vm/pull/312)
- Some cleanup in precompile error handling, see PR [#318](https://github.com/ethereumjs/ethereumjs-vm/pull/318)
- Some cleanup for ``StateManager``, see PR [#266](https://github.com/ethereumjs/ethereumjs-vm/pull/266)
- Renaming of ``util.sha3`` usages to ``util.keccak256`` and bump ``ethereumjs-util`` to ``v5.2.0`` (you should do to if you use ``ethereumjs-util``)
- Parallel testing of the``Byzantium`` and ``Constantinople`` state tests, see PR [#317](https://github.com/ethereumjs/ethereumjs-vm/pull/317)
- For lower build times our CI configuration now runs solely on ``CircleCI`` and support for ``Travis`` have been dropped, see PR [#316](https://github.com/ethereumjs/ethereumjs-vm/pull/316)
**BUG FIXES**
- Programmatic runtime errors in the VM execution context (within an opcode) are no longer absorbed and displayed as a VMError but explicitly thrown, allowing for easier discovery of implementation bugs, see PR [#307](https://github.com/ethereumjs/ethereumjs-vm/pull/307)
- Fix of the ``Bloom.check()`` method not working properly, see PR [#311](https://github.com/ethereumjs/ethereumjs-vm/pull/311)
- Fix a bug when ``REVERT`` is used within a ``CREATE`` context, see PR [#297](https://github.com/ethereumjs/ethereumjs-vm/pull/297)
- Fix a bug in ``FakeBlockChain`` error handing, see PR [#320](https://github.com/ethereumjs/ethereumjs-vm/pull/320)
[2.4.0]: https://github.com/ethereumjs/ethereumjs-vm/compare/v2.3.5...v2.4.0
## [2.3.5] - 2018-04-25

@@ -10,0 +57,0 @@

19

dist/bloom.js

@@ -9,2 +9,15 @@ 'use strict';

/**
* drops leading zeroes from a buffer
* @function dropLeadingZeroes
* @param {Buffer} buff
*/
function dropLeadingZeroes(buff) {
for (var i = 0; i < buff.length; i++) {
if (buff[i] !== 0) {
return buff.slice(i);
}
}
}
/**
* Represents a Bloom

@@ -29,3 +42,3 @@ * @constructor

Bloom.prototype.add = function (e) {
e = utils.sha3(e);
e = utils.keccak256(dropLeadingZeroes(e));
var mask = 2047; // binary 11111111111

@@ -48,4 +61,4 @@

Bloom.prototype.check = function (e) {
e = utils.sha3(e);
var mask = 511; // binary 111111111
e = utils.keccak256(dropLeadingZeroes(e));
var mask = 2047; // binary 11111111111
var match = true;

@@ -52,0 +65,0 @@

@@ -16,2 +16,3 @@ 'use strict';

this.error = error;
this.errorType = 'VmError';
}

@@ -18,0 +19,0 @@

6

dist/fakeBlockChain.js

@@ -11,7 +11,7 @@ 'use strict';

if (Buffer.isBuffer(blockTag)) {
_hash = utils.sha3(blockTag);
_hash = utils.keccak256(blockTag);
} else if (Number.isInteger(blockTag)) {
_hash = utils.sha3('0x' + utils.toBuffer(blockTag).toString('hex'));
_hash = utils.keccak256('0x' + utils.toBuffer(blockTag).toString('hex'));
} else {
cb(new Error('Unknown blockTag type'));
return cb(new Error('Unknown blockTag type'));
}

@@ -18,0 +18,0 @@

@@ -7,2 +7,3 @@ 'use strict';

var StateManager = require('./stateManager.js');
var Common = require('ethereumjs-common');
var Account = require('ethereumjs-account');

@@ -36,2 +37,4 @@ var AsyncEventEmitter = require('async-eventemitter');

* @param {Blockchain} [opts.blockchain] A blockchain object for storing/retrieving blocks (ignored if stateManager is passed)
* @param {String|Number} opts.chain The chain the VM operates on [default: 'mainnet']
* @param {String} opts.hardfork Hardfork rules to be used [default: 'byzantium', supported: 'byzantium' (will throw on unsupported)]
* @param {Boolean} [opts.activatePrecompiles] Create entries in the state tree for the precompiled contracts

@@ -45,2 +48,9 @@ * @param {Boolean} [opts.allowUnlimitedContractSize] Allows unlimited contract sizes while debugging (default: false; ONLY use during debugging)

var chain = opts.chain ? opts.chain : 'mainnet';
var hardfork = opts.hardfork ? opts.hardfork : 'byzantium';
var supportedHardforks = ['byzantium', // Officially supported
'constantinople' // No official support yet, only for testing reasons
];
this._common = new Common(chain, hardfork, supportedHardforks);
if (opts.stateManager) {

@@ -51,3 +61,4 @@ this.stateManager = opts.stateManager;

trie: opts.state,
blockchain: opts.blockchain
blockchain: opts.blockchain,
common: this._common
});

@@ -58,7 +69,2 @@ }

// temporary
// this is here for a gradual transition to StateManager
this.blockchain = this.stateManager.blockchain;
this.trie = this.stateManager.trie;
// precompiled contracts

@@ -77,3 +83,3 @@ this._precompiled = {};

for (var i = 1; i <= 7; i++) {
this.trie.put(new BN(i).toArrayLike(Buffer, 'be', 20), new Account().serialize());
this.stateManager.trie.put(new BN(i).toArrayLike(Buffer, 'be', 20), new Account().serialize());
}

@@ -102,3 +108,3 @@ }

VM.prototype.loadCompiled = function (address, src, cb) {
this.trie.db.put(address, src, cb);
this.stateManager.trie.db.put(address, src, cb);
};

@@ -105,0 +111,0 @@

@@ -31,2 +31,5 @@ 'use strict';

0x1a: ['BYTE', 3, 2, 1, false],
0x1b: ['SHL', 3, 2, 1, false],
0x1c: ['SHR', 3, 2, 1, false],
0x1d: ['SAR', 3, 2, 1, false],

@@ -33,0 +36,0 @@ // 0x20 range - crypto

@@ -5,3 +5,2 @@ 'use strict';

var async = require('async');
var fees = require('ethereum-common');
var utils = require('ethereumjs-util');

@@ -101,3 +100,3 @@ var BN = utils.BN;

var bytes = 1 + logTable(exponent);
subGas(runState, new BN(bytes).muln(fees.expByteGas.v));
subGas(runState, new BN(bytes).muln(runState._common.param('gasPrices', 'expByte')));
return base.redPow(exponent);

@@ -165,2 +164,41 @@ } else {

},
SHL: function SHL(a, b, runState) {
if (!runState._common.gteHardfork('constantinople')) {
trap(ERROR.INVALID_OPCODE);
}
if (a.gten(256)) {
return new BN(0);
}
return b.shln(a.toNumber()).iand(utils.MAX_INTEGER);
},
SHR: function SHR(a, b, runState) {
if (!runState._common.gteHardfork('constantinople')) {
trap(ERROR.INVALID_OPCODE);
}
if (a.gten(256)) {
return new BN(0);
}
return b.shrn(a.toNumber());
},
SAR: function SAR(a, b, runState) {
if (!runState._common.gteHardfork('constantinople')) {
trap(ERROR.INVALID_OPCODE);
}
var isSigned = b.testn(255);
if (a.gten(256)) {
if (isSigned) {
return new BN(utils.MAX_INTEGER);
} else {
return new BN(0);
}
}
var c = b.shrn(a.toNumber());
if (isSigned) {
var shiftedOutWidth = 255 - a.toNumber();
var mask = utils.MAX_INTEGER.shrn(shiftedOutWidth).shln(shiftedOutWidth);
return c.ior(mask);
} else {
return c;
}
},
// 0x20 range - crypto

@@ -170,4 +208,4 @@ SHA3: function SHA3(offset, length, runState) {

// copy fee
subGas(runState, new BN(fees.sha3WordGas.v).imul(length.divCeil(new BN(32))));
return new BN(utils.sha3(data));
subGas(runState, new BN(runState._common.param('gasPrices', 'sha3Word')).imul(length.divCeil(new BN(32))));
return new BN(utils.keccak256(data));
},

@@ -226,3 +264,3 @@ // 0x30 range - closure state

// sub the COPY fee
subGas(runState, new BN(fees.copyGas.v).imul(dataLength.divCeil(new BN(32))));
subGas(runState, new BN(runState._common.param('gasPrices', 'copy')).imul(dataLength.divCeil(new BN(32))));
},

@@ -235,3 +273,3 @@ CODESIZE: function CODESIZE(runState) {

// sub the COPY fee
subGas(runState, new BN(fees.copyGas.v).imul(length.divCeil(new BN(32))));
subGas(runState, new BN(runState._common.param('gasPrices', 'copy')).imul(length.divCeil(new BN(32))));
},

@@ -253,3 +291,3 @@ EXTCODESIZE: function EXTCODESIZE(address, runState, cb) {

// copy fee
subGas(runState, new BN(fees.copyGas.v).imul(length.divCeil(new BN(32))));
subGas(runState, new BN(runState._common.param('gasPrices', 'copy')).imul(length.divCeil(new BN(32))));

@@ -272,3 +310,3 @@ stateManager.getContractCode(address, function (err, code) {

// sub the COPY fee
subGas(runState, new BN(fees.copyGas.v).mul(length.divCeil(new BN(32))));
subGas(runState, new BN(runState._common.param('gasPrices', 'copy')).mul(length.divCeil(new BN(32))));
},

@@ -352,10 +390,10 @@ GASPRICE: function GASPRICE(runState) {

if (value.length === 0 && !found.length) {
subGas(runState, new BN(fees.sstoreResetGas.v));
subGas(runState, new BN(runState._common.param('gasPrices', 'sstoreReset')));
} else if (value.length === 0 && found.length) {
subGas(runState, new BN(fees.sstoreResetGas.v));
runState.gasRefund.iaddn(fees.sstoreRefundGas.v);
subGas(runState, new BN(runState._common.param('gasPrices', 'sstoreReset')));
runState.gasRefund.iaddn(runState._common.param('gasPrices', 'sstoreRefund'));
} else if (value.length !== 0 && !found.length) {
subGas(runState, new BN(fees.sstoreSetGas.v));
subGas(runState, new BN(runState._common.param('gasPrices', 'sstoreSet')));
} else if (value.length !== 0 && found.length) {
subGas(runState, new BN(fees.sstoreResetGas.v));
subGas(runState, new BN(runState._common.param('gasPrices', 'sstoreReset')));
}

@@ -459,3 +497,3 @@ } catch (e) {

var mem = memLoad(runState, memOffset, memLength);
subGas(runState, new BN(fees.logTopicGas.v).imuln(numOfTopics).iadd(memLength.muln(fees.logDataGas.v)));
subGas(runState, new BN(runState._common.param('gasPrices', 'logTopic')).imuln(numOfTopics).iadd(memLength.muln(runState._common.param('gasPrices', 'logData'))));

@@ -522,3 +560,3 @@ // add address

if (!value.isZero()) {
subGas(runState, new BN(fees.callValueTransferGas.v));
subGas(runState, new BN(runState._common.param('gasPrices', 'callValueTransfer')));
}

@@ -541,3 +579,3 @@

try {
subGas(runState, new BN(fees.callNewAccountGas.v));
subGas(runState, new BN(runState._common.param('gasPrices', 'callNewAccount')));
} catch (e) {

@@ -559,4 +597,4 @@ done(e.error);

if (!value.isZero()) {
runState.gasLeft.iaddn(fees.callStipend.v);
options.gasLimit.iaddn(fees.callStipend.v);
runState.gasLeft.iaddn(runState._common.param('gasPrices', 'callStipend'));
options.gasLimit.iaddn(runState._common.param('gasPrices', 'callStipend'));
}

@@ -590,3 +628,3 @@

if (!value.isZero()) {
subGas(runState, new BN(fees.callValueTransferGas.v));
subGas(runState, new BN(runState._common.param('gasPrices', 'callValueTransfer')));
}

@@ -598,4 +636,4 @@

if (!value.isZero()) {
runState.gasLeft.iaddn(fees.callStipend.v);
options.gasLimit.iaddn(fees.callStipend.v);
runState.gasLeft.iaddn(runState._common.param('gasPrices', 'callStipend'));
options.gasLimit.iaddn(runState._common.param('gasPrices', 'callStipend'));
}

@@ -744,3 +782,3 @@

try {
subGas(runState, new BN(fees.callNewAccountGas.v));
subGas(runState, new BN(runState._common.param('gasPrices', 'callNewAccount')));
} catch (e) {

@@ -755,3 +793,3 @@ cb(e.error);

if (!runState.selfdestruct[contractAddress.toString('hex')]) {
runState.gasRefund = runState.gasRefund.addn(fees.suicideRefundGas.v);
runState.gasRefund = runState.gasRefund.addn(runState._common.param('gasPrices', 'selfdestructRefund'));
}

@@ -772,3 +810,3 @@ runState.selfdestruct[contractAddress.toString('hex')] = selfdestructToAddress;

function describeLocation(runState) {
var hash = utils.sha3(runState.code).toString('hex');
var hash = utils.keccak256(runState.code).toString('hex');
var address = runState.address.toString('hex');

@@ -806,4 +844,4 @@ var pc = runState.programCounter - 1;

var words = newMemoryWordCount;
var fee = new BN(fees.memoryGas.v);
var quadCoeff = new BN(fees.quadCoeffDiv.v);
var fee = new BN(runState._common.param('gasPrices', 'memory'));
var quadCoeff = new BN(runState._common.param('gasPrices', 'quadCoeffDiv'));
// words * 3 + words ^2 / 512

@@ -948,3 +986,3 @@ var cost = words.mul(fee).add(words.mul(words).div(quadCoeff));

// Note: in the case of delegatecall, the value is persisted and doesn't need to be deducted again
if (runState.depth >= fees.stackLimit.v || callOptions.delegatecall !== true && new BN(runState.contract.balance).lt(callOptions.value)) {
if (runState.depth >= runState._common.param('vm', 'stackLimit') || callOptions.delegatecall !== true && new BN(runState.contract.balance).lt(callOptions.value)) {
cb(null, new BN(0));

@@ -951,0 +989,0 @@ } else {

@@ -6,3 +6,2 @@ 'use strict';

var error = require('../exceptions.js').ERROR;
var fees = require('ethereum-common');
var assert = require('assert');

@@ -15,5 +14,6 @@

results.gasUsed = new BN(fees.ecrecoverGas.v);
results.gasUsed = new BN(opts._common.param('gasPrices', 'ecRecover'));
if (opts.gasLimit.lt(results.gasUsed)) {
results.return = Buffer.alloc(0);
results.gasUsed = opts.gasLimit;

@@ -36,2 +36,4 @@ results.exception = 0; // 0 means VM fail (in this case because of OOG)

} catch (e) {
results.return = Buffer.alloc(0);
results.exception = 1;
return results;

@@ -38,0 +40,0 @@ }

@@ -6,3 +6,2 @@ 'use strict';

var error = require('../exceptions.js').ERROR;
var fees = require('ethereum-common');
var assert = require('assert');

@@ -16,6 +15,7 @@

results.gasUsed = new BN(fees.sha256Gas.v);
results.gasUsed.iadd(new BN(fees.sha256WordGas.v).imuln(Math.ceil(data.length / 32)));
results.gasUsed = new BN(opts._common.param('gasPrices', 'sha256'));
results.gasUsed.iadd(new BN(opts._common.param('gasPrices', 'sha256Word')).imuln(Math.ceil(data.length / 32)));
if (opts.gasLimit.lt(results.gasUsed)) {
results.return = Buffer.alloc(0);
results.gasUsed = opts.gasLimit;

@@ -22,0 +22,0 @@ results.exceptionError = error.OUT_OF_GAS;

@@ -6,3 +6,2 @@ 'use strict';

var error = require('../exceptions.js').ERROR;
var fees = require('ethereum-common');
var assert = require('assert');

@@ -16,6 +15,7 @@

results.gasUsed = new BN(fees.ripemd160Gas.v);
results.gasUsed.iadd(new BN(fees.ripemd160WordGas.v).imuln(Math.ceil(data.length / 32)));
results.gasUsed = new BN(opts._common.param('gasPrices', 'ripemd160'));
results.gasUsed.iadd(new BN(opts._common.param('gasPrices', 'ripemd160Word')).imuln(Math.ceil(data.length / 32)));
if (opts.gasLimit.lt(results.gasUsed)) {
results.return = Buffer.alloc(0);
results.gasUsed = opts.gasLimit;

@@ -22,0 +22,0 @@ results.exceptionError = error.OUT_OF_GAS;

@@ -5,3 +5,2 @@ 'use strict';

var BN = utils.BN;
var fees = require('ethereum-common');
var error = require('../exceptions.js').ERROR;

@@ -16,6 +15,7 @@ var assert = require('assert');

results.gasUsed = new BN(fees.identityGas.v);
results.gasUsed.iadd(new BN(fees.identityWordGas.v).imuln(Math.ceil(data.length / 32)));
results.gasUsed = new BN(opts._common.param('gasPrices', 'identity'));
results.gasUsed.iadd(new BN(opts._common.param('gasPrices', 'identityWord')).imuln(Math.ceil(data.length / 32)));
if (opts.gasLimit.lt(results.gasUsed)) {
results.return = Buffer.alloc(0);
results.gasUsed = opts.gasLimit;

@@ -22,0 +22,0 @@ results.exceptionError = error.OUT_OF_GAS;

@@ -6,7 +6,4 @@ 'use strict';

var error = require('../exceptions.js').ERROR;
var fees = require('ethereum-common');
var assert = require('assert');
var Gquaddivisor = fees.modexpGquaddivisor.v;
function multComplexity(x) {

@@ -31,5 +28,10 @@ var fac1 = new BN(0);

function getAdjustedExponentLength(data) {
var baseLen = new BN(data.slice(0, 32)).toNumber();
var expBytesStart;
try {
var baseLen = new BN(data.slice(0, 32)).toNumber();
expBytesStart = 96 + baseLen; // 96 for base length, then exponent length, and modulus length, then baseLen for the base data, then exponent bytes start
} catch (e) {
expBytesStart = Number.MAX_SAFE_INTEGER - 32;
}
var expLen = new BN(data.slice(32, 64));
var expBytesStart = 96 + baseLen; // 96 for base length, then exponent length, and modulus length, then baseLen for the base data, then exponent bytes start
var firstExpBytes = Buffer.from(data.slice(expBytesStart, expBytesStart + 32)); // first word of the exponent data

@@ -72,2 +74,3 @@ firstExpBytes = utils.setLengthRight(firstExpBytes, 32); // reading past the data reads virtual zeros

function getOOGResults(opts, results) {
results.return = Buffer.alloc(0);
results.gasUsed = opts.gasLimit;

@@ -98,2 +101,3 @@ results.exception = 0; // 0 means VM fail (in this case because of OOG)

}
var Gquaddivisor = opts._common.param('gasPrices', 'modexpGquaddivisor');
var gasUsed = adjustedELen.mul(multComplexity(maxLen)).divn(Gquaddivisor);

@@ -114,3 +118,3 @@

if (mLen.isZero()) {
results.return = Buffer.from([0]);
results.return = Buffer.alloc(0);
results.exception = 1;

@@ -117,0 +121,0 @@ return results;

@@ -6,7 +6,5 @@ 'use strict';

var error = require('../exceptions.js').ERROR;
var fees = require('ethereum-common');
var assert = require('assert');
var bn128Module = require('rustbn.js');
var ecAddPrecompile = bn128Module.cwrap('ec_add', 'string', ['string']);
var bn128 = require('rustbn.js');

@@ -17,6 +15,5 @@ module.exports = function (opts) {

var results = {};
var data = opts.data;
var inputHexStr = data.toString('hex');
var inputData = opts.data;
results.gasUsed = new BN(fees.ecAddGas.v);
results.gasUsed = new BN(opts._common.param('gasPrices', 'ecAdd'));
if (opts.gasLimit.lt(results.gasUsed)) {

@@ -30,6 +27,6 @@ results.return = Buffer.alloc(0);

var returnData = ecAddPrecompile(inputHexStr);
var returnData = bn128.add(inputData);
// check ecadd success or failure by comparing the output length
if (returnData.length !== 128) {
if (returnData.length !== 64) {
results.return = Buffer.alloc(0);

@@ -40,3 +37,3 @@ results.exception = 0;

} else {
results.return = Buffer.from(returnData, 'hex');
results.return = returnData;
results.exception = 1;

@@ -43,0 +40,0 @@ }

@@ -6,7 +6,5 @@ 'use strict';

var BN = utils.BN;
var fees = require('ethereum-common');
var assert = require('assert');
var bn128Module = require('rustbn.js');
var ecMulPrecompile = bn128Module.cwrap('ec_mul', 'string', ['string']);
var bn128 = require('rustbn.js');

@@ -17,6 +15,5 @@ module.exports = function (opts) {

var results = {};
var data = opts.data;
var inputData = opts.data;
var inputHexStr = data.toString('hex');
results.gasUsed = new BN(fees.ecMulGas.v);
results.gasUsed = new BN(opts._common.param('gasPrices', 'ecMul'));

@@ -31,10 +28,12 @@ if (opts.gasLimit.lt(results.gasUsed)) {

var returnData = ecMulPrecompile(inputHexStr);
var returnData = bn128.mul(inputData);
// check ecmul success or failure by comparing the output length
if (returnData.length !== 128) {
if (returnData.length !== 64) {
results.return = Buffer.alloc(0);
results.exception = 0;
results.gasUsed = new BN(opts.gasLimit);
results.exceptionError = ERROR.OUT_OF_GAS;
} else {
results.return = Buffer.from(returnData, 'hex');
results.return = returnData;
results.exception = 1;

@@ -41,0 +40,0 @@ }

@@ -6,7 +6,5 @@ 'use strict';

var error = require('../exceptions.js').ERROR;
var fees = require('ethereum-common');
var assert = require('assert');
var bn128Module = require('rustbn.js');
var ecPairingPrecompile = bn128Module.cwrap('ec_pairing', 'string', ['string']);
var bn128 = require('rustbn.js');

@@ -17,12 +15,12 @@ module.exports = function (opts) {

var results = {};
var data = opts.data;
var inputData = opts.data;
var inputHexStr = data.toString('hex');
var inputData = Buffer.from(inputHexStr, 'hex');
// no need to care about non-divisible-by-192, because bn128.pairing will properly fail in that case
var inputDataSize = Math.floor(inputData.length / 192);
var gascost = fees.ecPairingGas.v + inputDataSize * fees.ecPairingWordGas.v;
var gascost = opts._common.param('gasPrices', 'ecPairing') + inputDataSize * opts._common.param('gasPrices', 'ecPairingWord');
results.gasUsed = new BN(gascost);
if (opts.gasLimit.ltn(gascost)) {
results.return = Buffer.alloc(0);
results.gasUsed = opts.gasLimit;

@@ -34,6 +32,6 @@ results.exceptionError = error.OUT_OF_GAS;

var returnData = ecPairingPrecompile(inputHexStr);
var returnData = bn128.pairing(inputData);
// check ecpairing success or failure by comparing the output length
if (returnData.length !== 64) {
if (returnData.length !== 32) {
results.return = Buffer.alloc(0);

@@ -44,3 +42,3 @@ results.gasUsed = opts.gasLimit;

} else {
results.return = Buffer.from(returnData, 'hex');
results.return = returnData;
results.exception = 1;

@@ -47,0 +45,0 @@ }

@@ -7,3 +7,2 @@ 'use strict';

var Bloom = require('./bloom.js');
var common = require('ethereum-common');
var rlp = ethUtil.rlp;

@@ -13,4 +12,2 @@ var Trie = require('merkle-patricia-tree');

var minerReward = new BN(common.minerReward.v);
/**

@@ -44,3 +41,3 @@ * process the transaction in a block and pays the miners

this.trie.checkpoint();
self.stateManager.trie.checkpoint();

@@ -139,3 +136,3 @@ // run everything

if (err) {
self.trie.revert();
self.stateManager.trie.revert();
cb(err);

@@ -150,6 +147,6 @@ return;

if (generateStateRoot) {
block.header.stateRoot = self.trie.root;
block.header.stateRoot = self.stateManager.trie.root;
}
self.trie.commit(function (err) {
self.stateManager.trie.commit(function (err) {
self.stateManager.cache.flush(function () {

@@ -166,3 +163,3 @@ if (validateStateRoot) {

}
if (self.trie.root.toString('hex') !== block.header.stateRoot.toString('hex')) {
if (self.stateManager.trie.root.toString('hex') !== block.header.stateRoot.toString('hex')) {
err = new Error((err || '') + 'invalid block stateRoot ');

@@ -192,2 +189,3 @@ }

// calculate nibling reward
var minerReward = new BN(self._common.param('pow', 'minerReward'));
var niblingReward = minerReward.divn(32);

@@ -204,2 +202,3 @@ var totalNiblingReward = niblingReward.muln(ommers.length);

// calculate reward
var minerReward = new BN(self._common.param('pow', 'minerReward'));
var heightDiff = new BN(block.header.number).sub(new BN(ommer.number));

@@ -206,0 +205,0 @@ var reward = new BN(8).sub(heightDiff).mul(minerReward.divn(8));

@@ -14,13 +14,12 @@ 'use strict';

self.blockchain = self.stateManager.blockchain;
// parse arguments
if (typeof blockchain === 'function') {
cb = blockchain;
} else if (blockchain) {
self.blockchain = blockchain;
blockchain = undefined;
}
blockchain = blockchain || self.stateManager.blockchain;
// setup blockchain iterator
self.blockchain.iterator('vm', processBlock, cb);
blockchain.iterator('vm', processBlock, cb);
function processBlock(block, reorg, cb) {

@@ -33,3 +32,3 @@ async.series([getStartingState, runBlock], cb);

if (!headBlock || reorg) {
self.blockchain.getBlock(block.header.parentHash, function (err, parentBlock) {
blockchain.getBlock(block.header.parentHash, function (err, parentBlock) {
parentState = parentBlock.header.stateRoot;

@@ -59,3 +58,3 @@ // generate genesis state if we are at the genesis block

console.log('Invalid block error:', err);
self.blockchain.delBlock(block.header.hash(), cb);
blockchain.delBlock(block.header.hash(), cb);
} else {

@@ -62,0 +61,0 @@ // set as new head block

@@ -7,3 +7,2 @@ 'use strict';

var BN = ethUtil.BN;
var fees = require('ethereum-common');
var exceptions = require('./exceptions.js');

@@ -69,7 +68,24 @@

createdAddress = toAddress = ethUtil.generateAddress(caller, newNonce.toArray());
stateManager.getAccount(createdAddress, function (err, account) {
toAccount = account;
var NONCE_OFFSET = 1;
toAccount.nonce = new BN(toAccount.nonce).addn(NONCE_OFFSET).toArrayLike(Buffer);
done(err);
stateManager.clearContractStorage(createdAddress, function (err) {
if (err) {
done(err);
}
async.series([newContractEvent, getAccount], done);
function newContractEvent(callback) {
self.emit('newContract', {
address: createdAddress,
code: code
}, callback);
}
function getAccount(callback) {
stateManager.getAccount(createdAddress, function (err, account) {
toAccount = account;
var NONCE_OFFSET = 1;
toAccount.nonce = new BN(toAccount.nonce).addn(NONCE_OFFSET).toArrayLike(Buffer);
callback(err);
});
}
});

@@ -161,3 +177,3 @@ } else {

if (!results.runState.vmError) {
var returnFee = new BN(results.return.length * fees.createDataGas.v);
var returnFee = new BN(results.return.length * self._common.param('gasPrices', 'createData'));

@@ -164,0 +180,0 @@ totalGas = totalGas.add(returnFee);

@@ -83,3 +83,4 @@ 'use strict';

// temporary - to be factored out
};runState._precompiled = self._precompiled;
};runState._common = self._common;
runState._precompiled = self._precompiled;
runState._vm = self;

@@ -202,4 +203,8 @@

} catch (e) {
cb(e);
return;
if (e.errorType && e.errorType === 'VmError') {
cb(e);
return;
} else {
throw e;
}
}

@@ -211,3 +216,3 @@

// opcode post-stack mismatch
return cb(VmError(ERROR.INTERNAL_ERROR));
return cb(new VmError(ERROR.INTERNAL_ERROR));
}

@@ -219,3 +224,3 @@

// opcode post-stack mismatch
return cb(VmError(ERROR.INTERNAL_ERROR));
return cb(new VmError(ERROR.INTERNAL_ERROR));
}

@@ -222,0 +227,0 @@ }

@@ -7,7 +7,5 @@ 'use strict';

if (typeof opts.code === 'function') {
opts._common = this._common;
results = opts.code(opts);
results.account = opts.account;
if (results.exception === undefined) {
results.exception = 1;
}
cb(results.exceptionError, results);

@@ -14,0 +12,0 @@ } else {

@@ -5,3 +5,4 @@ 'use strict';

var Trie = require('merkle-patricia-tree/secure.js');
var common = require('ethereum-common');
var Common = require('ethereumjs-common');
var genesisStates = require('ethereumjs-common/genesisStates');
var async = require('async');

@@ -17,19 +18,18 @@ var Account = require('ethereumjs-account');

function StateManager(opts) {
function StateManager() {
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var self = this;
var trie = opts.trie;
if (!trie) {
trie = new Trie(trie);
}
self.blockchain = opts.blockchain || fakeBlockchain;
self.trie = opts.trie || new Trie();
var blockchain = opts.blockchain;
if (!blockchain) {
blockchain = fakeBlockchain;
var common = opts.common;
if (!common) {
common = new Common('mainnet', 'byzantium');
}
self._common = common;
self.blockchain = blockchain;
self.trie = trie;
self._storageTries = {}; // the storage trie cache
self.cache = new Cache(trie);
self.cache = new Cache(self.trie);
self._touched = new Set();

@@ -167,3 +167,3 @@ }

proto.putContractStorage = function (address, key, value, cb) {
proto._modifyContractStorage = function (address, modifyTrie, cb) {
var self = this;

@@ -175,10 +175,3 @@ self._getStorageTrie(address, function (err, storageTrie) {

if (value && value.length) {
// format input
var encodedValue = rlp.encode(value);
storageTrie.put(key, encodedValue, finalize);
} else {
// deleting a value
storageTrie.del(key, finalize);
}
modifyTrie(storageTrie, finalize);

@@ -198,2 +191,24 @@ function finalize(err) {

proto.putContractStorage = function (address, key, value, cb) {
var self = this;
self._modifyContractStorage(address, function (storageTrie, done) {
if (value && value.length) {
// format input
var encodedValue = rlp.encode(value);
storageTrie.put(key, encodedValue, done);
} else {
// deleting a value
storageTrie.del(key, done);
}
}, cb);
};
proto.clearContractStorage = function (address, cb) {
var self = this;
self._modifyContractStorage(address, function (storageTrie, done) {
storageTrie.root = storageTrie.EMPTY_TRIE_ROOT;
done();
}, cb);
};
proto.commitContracts = function (cb) {

@@ -302,3 +317,3 @@ var self = this;

proto.hasGenesisState = function (cb) {
var root = common.genesisStateRoot.v;
var root = this._common.genesis().stateRoot;
this.trie.checkRoot(root, cb);

@@ -312,3 +327,3 @@ };

if (!genesis && !err) {
self.generateGenesis(common.genesisState, cb);
self.generateGenesis(genesisStates[self._common.chainName()], cb);
} else {

@@ -315,0 +330,0 @@ cb(err);

{
"name": "ethereumjs-vm",
"version": "2.3.5",
"version": "2.4.0",
"description": "An Ethereum VM implementation",

@@ -13,3 +13,4 @@ "main": "dist/index.js",

"testVM": "node ./tests/tester -v",
"testState": "npm run build:dist && node ./tests/tester -s --dist",
"testStateByzantium": "npm run build:dist && node ./tests/tester -s --fork='Byzantium' --dist",
"testStateConstantinople": "npm run build:dist && node ./tests/tester -s --fork='Constantinople' --dist",
"testBuildIntegrity": "npm run build:dist && node ./tests/tester -s --dist --test='stackOverflow'",

@@ -37,10 +38,10 @@ "testBlockchain": "npm run build:dist && node --stack-size=1500 ./tests/tester -b --dist --excludeDir='GeneralStateTests'",

"async-eventemitter": "^0.2.2",
"ethereum-common": "0.2.0",
"ethereumjs-account": "^2.0.3",
"ethereumjs-block": "~1.7.0",
"ethereumjs-util": "^5.1.3",
"ethereumjs-common": "~0.4.0",
"ethereumjs-util": "^5.2.0",
"fake-merkle-patricia-tree": "^1.0.1",
"functional-red-black-tree": "^1.0.1",
"merkle-patricia-tree": "^2.1.2",
"rustbn.js": "~0.1.1",
"rustbn.js": "~0.2.0",
"safe-buffer": "^5.1.1"

@@ -53,3 +54,3 @@ },

"ethereumjs-blockchain": "~2.1.0",
"ethereumjs-testing": "https://github.com/ethereumjs/ethereumjs-testing",
"ethereumjs-testing": "git+https://github.com/ethereumjs/ethereumjs-testing.git#v1.1.1",
"ethereumjs-tx": "1.3.3",

@@ -56,0 +57,0 @@ "istanbul": "^0.4.5",

@@ -14,6 +14,22 @@ # SYNOPSIS

This library always only supports the currently active Ethereum mainnet fork rules with its latest release, old fork rules are dropped with new releases once a HF occured.
With the ``2.4.x`` release series we now start to gradually add ``Constantinople`` features with the
bitwise shifting instructions from [EIP 145](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md)
making the start being introduced in the ``v2.4.0`` release.
The current major [2.3.x](https://github.com/ethereumjs/ethereumjs-vm/releases) release series supports the [Byzantium](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-609.md) fork changes. 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)).
Since both the scope of the ``Constantinople`` hardfork as well as the state of at least some of the EIPs
to be included are not yet finalized, this is only meant for ``EXPERIMENTAL`` purposes, e.g. for developer
tools to give users early access and make themself familiar with dedicated features.
Once scope and EIPs from ``Constantinople`` are final we will target a ``v2.5.0`` release which will officially
introduce ``Constantinople`` support with all the changes bundled together.
Note that from this release on we also introduce new ``chain`` (default: ``mainnet``) and ``hardfork``
(default: ``byzantium``) parameters, which make use of our new [ethereumjs-common](https://github.com/ethereumjs/ethereumjs-common) library and in the future will allow
for parallel hardfork support from ``Byzantium`` onwards.
Since ``hardfork`` default might be changed or dropped in future releases, you might want to explicitly
set this to ``byzantium`` on your next update to avoid future unexpected behavior.
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)).
# INSTALL

@@ -54,4 +70,9 @@ `npm install ethereumjs-vm`

- [`vm.generateGenesis(cb)`](#vmgenerategenesiscb)
- [`VM` debugging hooks](#vm-debugging-hooks)
- [`vm.onStep`](#vmonstep)
- [`VM` Events](#events)
- [`step`](#step)
- [`newContract`](#newcontract)
- [`beforeBlock`](#beforeblock)
- [`afterBlock`](#afterblock)
- [`beforeTx`](#beforetx)
- [`afterTx`](#aftertx)

@@ -64,2 +85,4 @@ ### `new VM([opts])`

- `blockchain` - A blockchain object for storing/retrieving blocks (ignored if `stateManager` is passed)
- `chain` - The chain the VM operates on [default: 'mainnet']
- `hardfork` - Hardfork rules to be used [default: 'byzantium', supported: 'byzantium' (will throw on unsupported)]
- `activatePrecompiles` - Create entries in the state tree for the precompiled contracts

@@ -146,3 +169,3 @@ - `allowUnlimitedContractSize` - Allows unlimited contract sizes while debugging. By setting this to `true`, the check for contract size limit of 2KB (see [EIP-170](https://git.io/vxZkK)) is bypassed. (default: `false`; **ONLY** set to `true` during debugging).

### `events`
All events are instances of [async-eventemmiter](https://www.npmjs.com/package/async-eventemitter). If an event handler has an arity of 2 the VM will pause until the callback is called
All events are instances of [async-eventemmiter](https://www.npmjs.com/package/async-eventemitter). If an event handler has an arity of 2 the VM will pause until the callback is called, otherwise the VM will treat the event handler as a synchronous function.

@@ -162,2 +185,7 @@ #### `step`

#### `newContract`
The `newContract` event is given an `Object` and callback. The `Object` has the following properties.
- `address`: The created address for the new contract (type `Buffer | Uint8Array`)
- `code`: The deployment bytecode for reference (type `Buffer | Uint8Array`)
#### `beforeBlock`

@@ -164,0 +192,0 @@ Emits the block that is about to be processed.

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc