implement eip (#2245)

Signed-off-by: Karim TAAM <karim.t2am@gmail.com>
pull/2249/head
matkt 4 years ago committed by GitHub
parent 9b542bc7ec
commit 8d47d6c404
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 20
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolSpecs.java
  3. 46
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/contractvalidation/PrefixCodeRule.java
  4. 100
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetContractCreationProcessorTest.java

@ -6,6 +6,7 @@
* Added support for the upcoming BAIKAL ephemeral testnet and removed the configuration for the deprecated YOLOv3 ephemeral testnet. [\#2237](https://github.com/hyperledger/besu/pull/2237)
* Added support for the London Network Upgrade, although the block number must be set manually with `--override-genesis-config=londonBlock=<blocknumber>`. This is because the block numbers haven't been determined yet. The next release will include the number in the genesis file so it will support London with no intervention. [\#2237](https://github.com/hyperledger/besu/pull/2237)
* Implemented [EIP-3541](https://eips.ethereum.org/EIPS/eip-3541): Reject new contracts starting with the 0xEF byte [\#2243](https://github.com/hyperledger/besu/pull/2243)
### Bug Fixes

@ -37,6 +37,7 @@ import org.hyperledger.besu.ethereum.goquorum.GoQuorumBlockValidator;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecBuilder.BlockProcessorBuilder;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpecBuilder.BlockValidatorBuilder;
import org.hyperledger.besu.ethereum.mainnet.contractvalidation.MaxCodeSizeRule;
import org.hyperledger.besu.ethereum.mainnet.contractvalidation.PrefixCodeRule;
import org.hyperledger.besu.ethereum.privacy.PrivateTransactionProcessor;
import org.hyperledger.besu.ethereum.privacy.PrivateTransactionValidator;
import org.hyperledger.besu.ethereum.privacy.storage.PrivateMetadataUpdater;
@ -514,11 +515,13 @@ public abstract class MainnetProtocolSpecs {
static ProtocolSpecBuilder londonDefinition(
final Optional<BigInteger> chainId,
final OptionalInt contractSizeLimit,
final OptionalInt configContractSizeLimit,
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason,
final GenesisConfigOptions genesisConfigOptions,
final boolean quorumCompatibilityMode) {
final int contractSizeLimit =
configContractSizeLimit.orElse(SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT);
final Optional<TransactionPriceCalculator> transactionPriceCalculator =
Optional.of(TransactionPriceCalculator.eip1559());
final int stackSizeLimit = configStackSizeLimit.orElse(MessageFrame.DEFAULT_MAX_STACK_SIZE);
@ -526,7 +529,7 @@ public abstract class MainnetProtocolSpecs {
new EIP1559(genesisConfigOptions.getEIP1559BlockNumber().orElse(Long.MAX_VALUE));
return berlinDefinition(
chainId,
contractSizeLimit,
configContractSizeLimit,
configStackSizeLimit,
enableRevertReason,
quorumCompatibilityMode)
@ -557,16 +560,25 @@ public abstract class MainnetProtocolSpecs {
Account.DEFAULT_VERSION,
transactionPriceCalculator.orElseThrow(),
CoinbaseFeePriceCalculator.eip1559()))
.contractCreationProcessorBuilder(
(gasCalculator, evm) ->
new MainnetContractCreationProcessor(
gasCalculator,
evm,
true,
List.of(MaxCodeSizeRule.of(contractSizeLimit), PrefixCodeRule.of()),
1,
SPURIOUS_DRAGON_FORCE_DELETE_WHEN_EMPTY_ADDRESSES))
.evmBuilder(
gasCalculator ->
MainnetEvmRegistries.london(gasCalculator, chainId.orElse(BigInteger.ZERO)))
.name("London")
.transactionPriceCalculator(transactionPriceCalculator.orElseThrow())
.eip1559(Optional.of(eip1559))
.gasBudgetCalculator(TransactionGasBudgetCalculator.eip1559(eip1559))
.blockHeaderValidatorBuilder(MainnetBlockHeaderValidator.createEip1559Validator(eip1559))
.ommerHeaderValidatorBuilder(
MainnetBlockHeaderValidator.createEip1559OmmerValidator(eip1559));
MainnetBlockHeaderValidator.createEip1559OmmerValidator(eip1559))
.name("London");
}
private static TransactionReceipt frontierTransactionReceiptFactory(

@ -0,0 +1,46 @@
/*
* 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.contractvalidation;
import org.hyperledger.besu.ethereum.mainnet.ContractValidationRule;
import org.hyperledger.besu.ethereum.vm.MessageFrame;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class PrefixCodeRule implements ContractValidationRule {
private static final Logger LOG = LogManager.getLogger();
private final byte FORMAT_RESERVED = (byte) 0xEF;
@Override
// As per https://eips.ethereum.org/EIPS/eip-3541
public boolean validate(final MessageFrame frame) {
if (!frame.getOutputData().isEmpty()) {
if (frame.getOutputData().get(0) == FORMAT_RESERVED) {
LOG.trace("Contract creation error: code cannot start with {}", FORMAT_RESERVED);
return false;
} else {
return true;
}
}
return true;
}
public static ContractValidationRule of() {
return new PrefixCodeRule();
}
}

@ -0,0 +1,100 @@
/*
* 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 static org.assertj.core.api.Assertions.assertThat;
import static org.hyperledger.besu.ethereum.vm.MessageFrame.State.COMPLETED_SUCCESS;
import static org.hyperledger.besu.ethereum.vm.MessageFrame.State.EXCEPTIONAL_HALT;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.ethereum.core.Gas;
import org.hyperledger.besu.ethereum.core.MessageFrameTestFixture;
import org.hyperledger.besu.ethereum.mainnet.contractvalidation.PrefixCodeRule;
import org.hyperledger.besu.ethereum.vm.EVM;
import org.hyperledger.besu.ethereum.vm.GasCalculator;
import org.hyperledger.besu.ethereum.vm.MessageFrame;
import org.hyperledger.besu.ethereum.vm.OperationTracer;
import java.util.Collections;
import org.apache.tuweni.bytes.Bytes;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class MainnetContractCreationProcessorTest {
@Mock GasCalculator gasCalculator;
@Mock EVM evm;
private MainnetContractCreationProcessor processor;
@Test
public void shouldThrowAnExceptionWhenCodeContractFormatInvalid() {
processor =
new MainnetContractCreationProcessor(
gasCalculator,
evm,
true,
Collections.singletonList(PrefixCodeRule.of()),
1,
Collections.emptyList());
final Bytes contractCode = Bytes.fromHexString("EF01010101010101");
MessageFrame messageFrame = new MessageFrameTestFixture().build();
messageFrame.setOutputData(contractCode);
messageFrame.setGasRemaining(Gas.of(100));
when(gasCalculator.codeDepositGasCost(contractCode.size())).thenReturn(Gas.of(10));
processor.codeSuccess(messageFrame, OperationTracer.NO_TRACING);
assertThat(messageFrame.getState()).isEqualTo(EXCEPTIONAL_HALT);
}
@Test
public void shouldNotThrowAnExceptionWhenCodeContractIsValid() {
processor =
new MainnetContractCreationProcessor(
gasCalculator,
evm,
true,
Collections.singletonList(PrefixCodeRule.of()),
1,
Collections.emptyList());
final Bytes contractCode = Bytes.fromHexString("0101010101010101");
MessageFrame messageFrame = new MessageFrameTestFixture().build();
messageFrame.setOutputData(contractCode);
messageFrame.setGasRemaining(Gas.of(100));
when(gasCalculator.codeDepositGasCost(contractCode.size())).thenReturn(Gas.of(10));
processor.codeSuccess(messageFrame, OperationTracer.NO_TRACING);
assertThat(messageFrame.getState()).isEqualTo(COMPLETED_SUCCESS);
}
@Test
public void shouldNotThrowAnExceptionWhenPrefixCodeRuleNotAdded() {
processor =
new MainnetContractCreationProcessor(
gasCalculator, evm, true, Collections.emptyList(), 1, Collections.emptyList());
final Bytes contractCode = Bytes.fromHexString("0F01010101010101");
MessageFrame messageFrame = new MessageFrameTestFixture().build();
messageFrame.setOutputData(contractCode);
messageFrame.setGasRemaining(Gas.of(100));
when(gasCalculator.codeDepositGasCost(contractCode.size())).thenReturn(Gas.of(10));
processor.codeSuccess(messageFrame, OperationTracer.NO_TRACING);
assertThat(messageFrame.getState()).isEqualTo(COMPLETED_SUCCESS);
}
}
Loading…
Cancel
Save