diff --git a/lib/opFns.js b/lib/opFns.js index c85340d6369..25d5acb029b 100644 --- a/lib/opFns.js +++ b/lib/opFns.js @@ -7,6 +7,17 @@ const constants = require('./constants.js') const logTable = require('./logTable.js') const ERROR = constants.ERROR +// Find Ceil(`this` / `num`) +BN.prototype.divCeil = function divCeil (num) { + var dm = this.divmod(num); + + // Fast case - exact division + if (dm.mod.isZero()) return dm.div; + + // Round up + return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1); +}; + // the opcode functions module.exports = { STOP: function (runState) { @@ -199,7 +210,7 @@ module.exports = { length = new BN(length) var data = memLoad(runState, offset, length) // copy fee - subGas(runState, new BN(fees.sha3WordGas.v).imul(length.divRound(new BN(32)))) + subGas(runState, new BN(fees.sha3WordGas.v).imul(length.divCeil(new BN(32)))) return utils.sha3(data) }, // 0x30 range - closure state @@ -257,7 +268,7 @@ module.exports = { memStore(runState, memOffset, runState.callData, dataOffset, dataLength) // sub the COPY fee - subGas(runState, new BN(fees.copyGas.v).imul(dataLength.divRound(new BN(32)))) + subGas(runState, new BN(fees.copyGas.v).imul(dataLength.divCeil(new BN(32)))) }, CODESIZE: function (runState) { return utils.intToBuffer(runState.code.length) @@ -269,7 +280,7 @@ module.exports = { memStore(runState, memOffset, runState.code, codeOffset, length) // sub the COPY fee - subGas(runState, new BN(fees.copyGas.v).imul(length.divRound(new BN(32)))) + subGas(runState, new BN(fees.copyGas.v).imul(length.divCeil(new BN(32)))) }, EXTCODESIZE: function (address, runState, cb) { var stateManager = runState.stateManager @@ -289,7 +300,7 @@ module.exports = { // FIXME: for some reason this must come before subGas subMemUsage(runState, memOffset, length) // copy fee - subGas(runState, new BN(fees.copyGas.v).imul(length.divRound(new BN(32)))) + subGas(runState, new BN(fees.copyGas.v).imul(length.divCeil(new BN(32)))) stateManager.getContractCode(address, function (err, code) { if (err) return cb(err) @@ -769,7 +780,7 @@ function trap (err) { * @return {String} */ function subMemUsage (runState, offset, length) { - const newMemoryWordCount = offset.add(length).divRound(new BN(32)) + const newMemoryWordCount = offset.add(length).divCeil(new BN(32)) if (newMemoryWordCount.lte(runState.memoryWordCount)) return runState.memoryWordCount = newMemoryWordCount