mirror of https://github.com/hyperledger/besu
parent
a388144f79
commit
3267501c8c
@ -0,0 +1,84 @@ |
|||||||
|
/* |
||||||
|
* Copyright ConsenSys AG. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||||
|
* the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||||
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations under the License. |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
package org.hyperledger.besu.ethereum.mainnet; |
||||||
|
|
||||||
|
import org.hyperledger.besu.ethereum.core.Account; |
||||||
|
import org.hyperledger.besu.ethereum.core.Gas; |
||||||
|
|
||||||
|
import org.apache.tuweni.units.bigints.UInt256; |
||||||
|
|
||||||
|
public class LondonGasCalculator extends BerlinGasCalculator { |
||||||
|
|
||||||
|
// redefinitions for EIP-3529
|
||||||
|
private static final Gas SSTORE_CLEARS_SCHEDULE = SSTORE_RESET_GAS.plus(ACCESS_LIST_STORAGE_COST); |
||||||
|
|
||||||
|
private static final Gas NEGATIVE_SSTORE_CLEARS_SCHEDULE = Gas.ZERO.minus(SSTORE_CLEARS_SCHEDULE); |
||||||
|
|
||||||
|
// redefinitions for EIP-3529
|
||||||
|
private static final int NEW_MAX_REFUND_QUOTIENT = 5; |
||||||
|
|
||||||
|
protected LondonGasCalculator() {} |
||||||
|
|
||||||
|
// Redefined refund amount from EIP-3529
|
||||||
|
@Override |
||||||
|
public Gas getSelfDestructRefundAmount() { |
||||||
|
return Gas.ZERO; |
||||||
|
} |
||||||
|
|
||||||
|
// defined in Berlin, but re-implemented with new constants
|
||||||
|
@Override |
||||||
|
// As per https://eips.ethereum.org/EIPS/eip-3529
|
||||||
|
public Gas calculateStorageRefundAmount( |
||||||
|
final Account account, final UInt256 key, final UInt256 newValue) { |
||||||
|
final UInt256 currentValue = account.getStorageValue(key); |
||||||
|
if (currentValue.equals(newValue)) { |
||||||
|
return Gas.ZERO; |
||||||
|
} else { |
||||||
|
final UInt256 originalValue = account.getOriginalStorageValue(key); |
||||||
|
if (originalValue.equals(currentValue)) { |
||||||
|
if (originalValue.isZero()) { |
||||||
|
return Gas.ZERO; |
||||||
|
} else if (newValue.isZero()) { |
||||||
|
return SSTORE_CLEARS_SCHEDULE; |
||||||
|
} else { |
||||||
|
return Gas.ZERO; |
||||||
|
} |
||||||
|
} else { |
||||||
|
Gas refund = Gas.ZERO; |
||||||
|
if (!originalValue.isZero()) { |
||||||
|
if (currentValue.isZero()) { |
||||||
|
refund = NEGATIVE_SSTORE_CLEARS_SCHEDULE; |
||||||
|
} else if (newValue.isZero()) { |
||||||
|
refund = SSTORE_CLEARS_SCHEDULE; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (originalValue.equals(newValue)) { |
||||||
|
refund = |
||||||
|
refund.plus( |
||||||
|
originalValue.isZero() |
||||||
|
? SSTORE_SET_GAS_LESS_SLOAD_GAS |
||||||
|
: SSTORE_RESET_GAS_LESS_SLOAD_GAS); |
||||||
|
} |
||||||
|
return refund; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public long getMaxRefundQuotient() { |
||||||
|
return NEW_MAX_REFUND_QUOTIENT; |
||||||
|
}; |
||||||
|
} |
@ -0,0 +1,106 @@ |
|||||||
|
/* |
||||||
|
* Copyright ConsenSys AG. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||||
|
* the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||||
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations under the License. |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
package org.hyperledger.besu.ethereum.vm.operations; |
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat; |
||||||
|
|
||||||
|
import org.hyperledger.besu.config.StubGenesisConfigOptions; |
||||||
|
import org.hyperledger.besu.config.experimental.ExperimentalEIPs; |
||||||
|
import org.hyperledger.besu.ethereum.core.Account; |
||||||
|
import org.hyperledger.besu.ethereum.core.Gas; |
||||||
|
import org.hyperledger.besu.ethereum.core.TestCodeExecutor; |
||||||
|
import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule; |
||||||
|
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; |
||||||
|
import org.hyperledger.besu.ethereum.vm.MessageFrame; |
||||||
|
import org.hyperledger.besu.ethereum.vm.MessageFrame.State; |
||||||
|
|
||||||
|
import org.apache.tuweni.units.bigints.UInt256; |
||||||
|
import org.junit.After; |
||||||
|
import org.junit.Before; |
||||||
|
import org.junit.Test; |
||||||
|
import org.junit.runner.RunWith; |
||||||
|
import org.junit.runners.Parameterized; |
||||||
|
import org.junit.runners.Parameterized.Parameter; |
||||||
|
import org.junit.runners.Parameterized.Parameters; |
||||||
|
|
||||||
|
@RunWith(Parameterized.class) |
||||||
|
public class LondonSStoreOperationGasCostTest { |
||||||
|
|
||||||
|
private static ProtocolSchedule protocolSchedule; |
||||||
|
|
||||||
|
@Parameters(name = "Code: {0}, Original: {1}") |
||||||
|
public static Object[][] scenarios() { |
||||||
|
// Tests specified in EIP-3539.
|
||||||
|
return new Object[][] { |
||||||
|
{"0x60006000556000600055", 0, 212, 0}, |
||||||
|
{"0x60006000556001600055", 0, 20112, 0}, |
||||||
|
{"0x60016000556000600055", 0, 20112, 19900}, |
||||||
|
{"0x60016000556002600055", 0, 20112, 0}, |
||||||
|
{"0x60016000556001600055", 0, 20112, 0}, |
||||||
|
{"0x60006000556000600055", 1, 3012, 4800}, |
||||||
|
{"0x60006000556001600055", 1, 3012, 2800}, |
||||||
|
{"0x60006000556002600055", 1, 3012, 0}, |
||||||
|
{"0x60026000556000600055", 1, 3012, 4800}, |
||||||
|
{"0x60026000556003600055", 1, 3012, 0}, |
||||||
|
{"0x60026000556001600055", 1, 3012, 2800}, |
||||||
|
{"0x60026000556002600055", 1, 3012, 0}, |
||||||
|
{"0x60016000556000600055", 1, 3012, 4800}, |
||||||
|
{"0x60016000556002600055", 1, 3012, 0}, |
||||||
|
{"0x60016000556001600055", 1, 212, 0}, |
||||||
|
{"0x600160005560006000556001600055", 0, 40118, 19900}, |
||||||
|
{"0x600060005560016000556000600055", 1, 5918, 7600}, |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
private TestCodeExecutor codeExecutor; |
||||||
|
|
||||||
|
@Parameter public String code; |
||||||
|
|
||||||
|
@Parameter(value = 1) |
||||||
|
public int originalValue; |
||||||
|
|
||||||
|
@Parameter(value = 2) |
||||||
|
public int expectedGasUsed; |
||||||
|
|
||||||
|
@Parameter(value = 3) |
||||||
|
public int expectedGasRefund; |
||||||
|
|
||||||
|
@Before |
||||||
|
public void setUp() { |
||||||
|
ExperimentalEIPs.eip1559Enabled = true; |
||||||
|
protocolSchedule = |
||||||
|
MainnetProtocolSchedule.fromConfig(new StubGenesisConfigOptions().londonBlock(0)); |
||||||
|
codeExecutor = new TestCodeExecutor(protocolSchedule); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void shouldCalculateGasAccordingToEip3529() { |
||||||
|
final long gasLimit = 1_000_000; |
||||||
|
final MessageFrame frame = |
||||||
|
codeExecutor.executeCode( |
||||||
|
code, |
||||||
|
Account.DEFAULT_VERSION, |
||||||
|
gasLimit, |
||||||
|
account -> account.setStorageValue(UInt256.ZERO, UInt256.valueOf(originalValue))); |
||||||
|
assertThat(frame.getState()).isEqualTo(State.COMPLETED_SUCCESS); |
||||||
|
assertThat(frame.getRemainingGas()).isEqualTo(Gas.of(gasLimit - (expectedGasUsed + 2100))); |
||||||
|
assertThat(frame.getGasRefund()).isEqualTo(Gas.of(expectedGasRefund)); |
||||||
|
} |
||||||
|
|
||||||
|
@After |
||||||
|
public void reset() { |
||||||
|
ExperimentalEIPs.eip1559Enabled = ExperimentalEIPs.EIP1559_ENABLED_DEFAULT_VALUE; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue