@polygon-hermez/vm
Version:
An Ethereum VM implementation
65 lines • 3.17 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateSstoreGasEIP2200 = void 0;
const ethereumjs_util_1 = require("ethereumjs-util");
const exceptions_1 = require("../../exceptions");
const EIP2929_1 = require("./EIP2929");
const util_1 = require("./util");
/**
* Adjusts gas usage and refunds of SStore ops per EIP-2200 (Istanbul)
*
* @param {RunState} runState
* @param {Buffer} currentStorage
* @param {Buffer} originalStorage
* @param {Buffer} value
* @param {Common} common
*/
function updateSstoreGasEIP2200(runState, currentStorage, originalStorage, value, key, common) {
// Fail if not enough gas is left
if (runState.eei.getGasLeft().lten(common.param('gasPrices', 'sstoreSentryGasEIP2200'))) {
(0, util_1.trap)(exceptions_1.ERROR.OUT_OF_GAS);
}
// Noop
if (currentStorage.equals(value)) {
const sstoreNoopCost = new ethereumjs_util_1.BN(common.param('gasPrices', 'sstoreNoopGasEIP2200'));
return (0, EIP2929_1.adjustSstoreGasEIP2929)(runState, key, sstoreNoopCost, 'noop', common);
}
if (originalStorage.equals(currentStorage)) {
// Create slot
if (originalStorage.length === 0) {
return new ethereumjs_util_1.BN(common.param('gasPrices', 'sstoreInitGasEIP2200'));
}
// Delete slot
if (value.length === 0) {
runState.eei.refundGas(new ethereumjs_util_1.BN(common.param('gasPrices', 'sstoreClearRefundEIP2200')), 'EIP-2200 -> sstoreClearRefundEIP2200');
}
// Write existing slot
return new ethereumjs_util_1.BN(common.param('gasPrices', 'sstoreCleanGasEIP2200'));
}
if (originalStorage.length > 0) {
if (currentStorage.length === 0) {
// Recreate slot
runState.eei.subRefund(new ethereumjs_util_1.BN(common.param('gasPrices', 'sstoreClearRefundEIP2200')), 'EIP-2200 -> sstoreClearRefundEIP2200');
}
else if (value.length === 0) {
// Delete slot
runState.eei.refundGas(new ethereumjs_util_1.BN(common.param('gasPrices', 'sstoreClearRefundEIP2200')), 'EIP-2200 -> sstoreClearRefundEIP2200');
}
}
if (originalStorage.equals(value)) {
if (originalStorage.length === 0) {
// Reset to original non-existent slot
const sstoreInitRefund = new ethereumjs_util_1.BN(common.param('gasPrices', 'sstoreInitRefundEIP2200'));
runState.eei.refundGas((0, EIP2929_1.adjustSstoreGasEIP2929)(runState, key, sstoreInitRefund, 'initRefund', common), 'EIP-2200 -> initRefund');
}
else {
// Reset to original existing slot
const sstoreCleanRefund = new ethereumjs_util_1.BN(common.param('gasPrices', 'sstoreCleanRefundEIP2200'));
runState.eei.refundGas((0, EIP2929_1.adjustSstoreGasEIP2929)(runState, key, sstoreCleanRefund, 'cleanRefund', common), 'EIP-2200 -> cleanRefund');
}
}
// Dirty update
return new ethereumjs_util_1.BN(common.param('gasPrices', 'sstoreDirtyGasEIP2200'));
}
exports.updateSstoreGasEIP2200 = updateSstoreGasEIP2200;
//# sourceMappingURL=EIP2200.js.map