mirror of
https://github.com/vacp2p/status-linea-besu.git
synced 2026-01-08 23:08:15 -05:00
Merge branch 'main' into zkbesu
# Conflicts: # .github/workflows/draft-release.yml
This commit is contained in:
@@ -21,6 +21,7 @@ import static org.hyperledger.besu.evm.internal.Words.clampedToLong;
|
||||
import static org.hyperledger.besu.evm.internal.Words.numWords;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.Transaction;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
import org.hyperledger.besu.evm.account.Account;
|
||||
import org.hyperledger.besu.evm.frame.MessageFrame;
|
||||
@@ -566,4 +567,25 @@ public class FrontierGasCalculator implements GasCalculator {
|
||||
public long getMinimumTransactionCost() {
|
||||
return TX_BASE_COST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long calculateGasRefund(
|
||||
final Transaction transaction,
|
||||
final MessageFrame initialFrame,
|
||||
final long codeDelegationRefund) {
|
||||
final long selfDestructRefund =
|
||||
getSelfDestructRefundAmount() * initialFrame.getSelfDestructs().size();
|
||||
final long baseRefundGas =
|
||||
initialFrame.getGasRefund() + selfDestructRefund + codeDelegationRefund;
|
||||
return refunded(transaction, initialFrame.getRemainingGas(), baseRefundGas);
|
||||
}
|
||||
|
||||
private long refunded(
|
||||
final Transaction transaction, final long gasRemaining, final long gasRefund) {
|
||||
// Integer truncation takes care of the floor calculation needed after the divide.
|
||||
final long maxRefundAllowance =
|
||||
(transaction.getGasLimit() - gasRemaining) / getMaxRefundQuotient();
|
||||
final long refundAllowance = Math.min(maxRefundAllowance, gasRefund);
|
||||
return gasRemaining + refundAllowance;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ package org.hyperledger.besu.evm.gascalculator;
|
||||
|
||||
import org.hyperledger.besu.datatypes.AccessListEntry;
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.Transaction;
|
||||
import org.hyperledger.besu.datatypes.Wei;
|
||||
import org.hyperledger.besu.evm.account.Account;
|
||||
import org.hyperledger.besu.evm.frame.MessageFrame;
|
||||
@@ -664,4 +665,15 @@ public interface GasCalculator {
|
||||
default long calculateDelegateCodeGasRefund(final long alreadyExistingAccountSize) {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the gas refund for a transaction.
|
||||
*
|
||||
* @param transaction the transaction
|
||||
* @param initialFrame the initial frame
|
||||
* @param codeDelegationRefund the code delegation refund
|
||||
* @return the gas refund
|
||||
*/
|
||||
long calculateGasRefund(
|
||||
Transaction transaction, MessageFrame initialFrame, long codeDelegationRefund);
|
||||
}
|
||||
|
||||
@@ -16,8 +16,10 @@ package org.hyperledger.besu.evm.precompile;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/** Encapsulates a group of {@link PrecompiledContract}s used together. */
|
||||
public class PrecompileContractRegistry {
|
||||
@@ -48,4 +50,13 @@ public class PrecompileContractRegistry {
|
||||
public void put(final Address address, final PrecompiledContract precompile) {
|
||||
precompiles.put(address, precompile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the addresses of the precompiled contracts.
|
||||
*
|
||||
* @return the addresses
|
||||
*/
|
||||
public Set<Address> getPrecompileAddresses() {
|
||||
return Collections.unmodifiableSet(precompiles.keySet());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -37,7 +38,8 @@ import org.slf4j.LoggerFactory;
|
||||
public class MessageCallProcessor extends AbstractMessageProcessor {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MessageCallProcessor.class);
|
||||
|
||||
private final PrecompileContractRegistry precompiles;
|
||||
/** The precompiles. */
|
||||
protected final PrecompileContractRegistry precompiles;
|
||||
|
||||
/**
|
||||
* Instantiates a new Message call processor.
|
||||
@@ -171,4 +173,14 @@ public class MessageCallProcessor extends AbstractMessageProcessor {
|
||||
frame.setExceptionalHaltReason(result.getHaltReason());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the precompile addresses.
|
||||
*
|
||||
* @return the precompile addresses
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public Set<Address> getPrecompileAddresses() {
|
||||
return precompiles.getPrecompileAddresses();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright contributors to Besu.
|
||||
*
|
||||
* 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.evm.processor;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.evm.precompile.PrecompileContractRegistry;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A message call processor designed specifically for simulation purposes that allows for overriding
|
||||
* precompile addresses.
|
||||
*/
|
||||
public class OverriddenPrecompilesMessageCallProcessor extends MessageCallProcessor {
|
||||
|
||||
/**
|
||||
* Instantiates a new Modifiable precompiles message call processor for simulation.
|
||||
*
|
||||
* @param originalProcessor the original processor
|
||||
* @param precompileOverrides the address overrides
|
||||
*/
|
||||
public OverriddenPrecompilesMessageCallProcessor(
|
||||
final MessageCallProcessor originalProcessor,
|
||||
final Map<Address, Address> precompileOverrides) {
|
||||
super(
|
||||
originalProcessor.evm,
|
||||
createRegistryWithPrecompileOverrides(originalProcessor.precompiles, precompileOverrides));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new PrecompileContractRegistry with the specified address overrides.
|
||||
*
|
||||
* @param originalRegistry the original precompile contract registry
|
||||
* @param precompileOverrides the address overrides
|
||||
* @return a new PrecompileContractRegistry with the overrides applied
|
||||
*/
|
||||
private static PrecompileContractRegistry createRegistryWithPrecompileOverrides(
|
||||
final PrecompileContractRegistry originalRegistry,
|
||||
final Map<Address, Address> precompileOverrides) {
|
||||
PrecompileContractRegistry newRegistry = new PrecompileContractRegistry();
|
||||
for (Address originalAddress : originalRegistry.getPrecompileAddresses()) {
|
||||
Address effectiveAddress = precompileOverrides.getOrDefault(originalAddress, originalAddress);
|
||||
newRegistry.put(effectiveAddress, originalRegistry.get(originalAddress));
|
||||
}
|
||||
return newRegistry;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright contributors to Hyperledger Besu.
|
||||
*
|
||||
* 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.evm.gascalculator;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.hyperledger.besu.datatypes.Address;
|
||||
import org.hyperledger.besu.datatypes.Transaction;
|
||||
import org.hyperledger.besu.evm.frame.MessageFrame;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.tuweni.bytes.Bytes;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class FrontierGasCalculatorTest {
|
||||
private final GasCalculator gasCalculator = new FrontierGasCalculator();
|
||||
|
||||
@Mock private Transaction transaction;
|
||||
@Mock private MessageFrame messageFrame;
|
||||
|
||||
@Test
|
||||
void shouldCalculateRefundWithNoSelfDestructs() {
|
||||
// Arrange
|
||||
when(messageFrame.getSelfDestructs()).thenReturn(Collections.emptySet());
|
||||
when(messageFrame.getGasRefund()).thenReturn(1000L);
|
||||
when(messageFrame.getRemainingGas()).thenReturn(5000L);
|
||||
when(transaction.getGasLimit()).thenReturn(100000L);
|
||||
|
||||
// Act
|
||||
long refund = gasCalculator.calculateGasRefund(transaction, messageFrame, 500L);
|
||||
|
||||
// Assert
|
||||
assertThat(refund)
|
||||
.isEqualTo(6500L); // 5000 (remaining) + min(1500 (total refund), 19000 (max allowance))
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldCalculateRefundWithMultipleSelfDestructs() {
|
||||
// Arrange
|
||||
Set<Address> selfDestructs = new HashSet<>();
|
||||
selfDestructs.add(Address.wrap(Bytes.random(20)));
|
||||
selfDestructs.add(Address.wrap(Bytes.random(20)));
|
||||
|
||||
when(messageFrame.getSelfDestructs()).thenReturn(selfDestructs);
|
||||
when(messageFrame.getGasRefund()).thenReturn(1000L);
|
||||
when(messageFrame.getRemainingGas()).thenReturn(5000L);
|
||||
when(transaction.getGasLimit()).thenReturn(100000L);
|
||||
|
||||
// Act
|
||||
long refund = gasCalculator.calculateGasRefund(transaction, messageFrame, 500L);
|
||||
|
||||
// Assert
|
||||
assertThat(refund)
|
||||
.isEqualTo(52500L); // 5000 (remaining) + min(47500 (total refund), 49500 (max allowance))
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRespectMaxRefundAllowance() {
|
||||
// Arrange
|
||||
when(messageFrame.getSelfDestructs()).thenReturn(Collections.emptySet());
|
||||
when(messageFrame.getGasRefund()).thenReturn(100000L);
|
||||
when(messageFrame.getRemainingGas()).thenReturn(20000L);
|
||||
when(transaction.getGasLimit()).thenReturn(100000L);
|
||||
|
||||
// Act
|
||||
long refund = gasCalculator.calculateGasRefund(transaction, messageFrame, 1000L);
|
||||
|
||||
// Assert
|
||||
assertThat(refund)
|
||||
.isEqualTo(60000L); // 20000 (remaining) + min(101000 (total refund), 40000 (max allowance))
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldHandleZeroValuesCorrectly() {
|
||||
// Arrange
|
||||
when(messageFrame.getSelfDestructs()).thenReturn(Collections.emptySet());
|
||||
when(messageFrame.getGasRefund()).thenReturn(0L);
|
||||
when(messageFrame.getRemainingGas()).thenReturn(0L);
|
||||
when(transaction.getGasLimit()).thenReturn(100000L);
|
||||
|
||||
// Act
|
||||
long refund = gasCalculator.calculateGasRefund(transaction, messageFrame, 0L);
|
||||
|
||||
// Assert
|
||||
assertThat(refund).isEqualTo(0L);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user