diff --git a/.github/ISSUE_TEMPLATE/release-checklist.md b/.github/ISSUE_TEMPLATE/release-checklist.md new file mode 100644 index 0000000000..f484b7a590 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/release-checklist.md @@ -0,0 +1,35 @@ +--- +name: Release Checklist +about: items to be completed for each release +title: '' +labels: '' +assignees: '' + +--- + +- [ ] Confirm anything outstanding for release with other maintainers on #besu-release in Discord + - [ ] Notify maintainers about updating changelog for in-flight PRs + - [ ] Update changelog if necessary, and merge a PR for it to main +- [ ] Optional: for hotfixes, create a release branch and cherry-pick, e.g. `release--hotfix` +- [ ] Optional: create a PR into main from the hotfix branch to see the CI checks pass +- [ ] On the appropriate branch/commit, create a calver tag for the release candidate, format example: `24.4.0-RC2` +- [ ] Sign-off with team; confirm tag is correct in #besu-release in Discord +- [ ] Consensys staff start burn-in using the proposed release tag +- [ ] Sign off burn-in; convey burn-in results in #besu-release in Discord +- [ ] Using the same git sha, create a calver tag for the FULL RELEASE, example format `24.4.0` +- [ ] Using the FULL RELEASE tag, create a release in github to trigger the workflows. Once published: + - makes the release "latest" in github + - this is now public and notifies subscribed users + - publishes artefacts and version-specific docker tags + - publishes the docker `latest` tag variants +- [ ] Draft homebrew PR +- [ ] Draft documentation release +- [ ] Ensure binary SHAs are correct on the release page +- [ ] Docker release startup test: + - `docker run hyperledger/besu:` + - `docker run hyperledger/besu:-arm64` + - `docker run --platform linux/amd64 hyperledger/besu:-amd64` + - `docker run --pull=always hyperledger/besu:latest` (check version is ) +- [ ] Merge homebrew PR +- [ ] Publish Docs Release +- [ ] Social announcements diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningOutOfSyncAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningOutOfSyncAcceptanceTest.java index 935db106ca..de888904fd 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningOutOfSyncAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodeSmartContractPermissioningOutOfSyncAcceptanceTest.java @@ -17,6 +17,7 @@ package org.hyperledger.besu.tests.acceptance.permissioning; import org.hyperledger.besu.tests.acceptance.dsl.node.Node; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; public class NodeSmartContractPermissioningOutOfSyncAcceptanceTest @@ -42,6 +43,7 @@ public class NodeSmartContractPermissioningOutOfSyncAcceptanceTest } @Test + @Disabled("test is flaky #7108") public void addNodeToClusterAndVerifyNonBootNodePeerConnectionWorksAfterSync() { final long blockchainHeight = 25L; waitForBlockHeight(permissionedNodeA, blockchainHeight); diff --git a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodesSmartContractPermissioningStaticNodesAcceptanceTest.java b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodesSmartContractPermissioningStaticNodesAcceptanceTest.java index 4f516d1cda..898f0e47ad 100644 --- a/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodesSmartContractPermissioningStaticNodesAcceptanceTest.java +++ b/acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/permissioning/NodesSmartContractPermissioningStaticNodesAcceptanceTest.java @@ -25,8 +25,10 @@ import java.util.List; import javax.annotation.Nonnull; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +@Disabled("flaky test #7155") public class NodesSmartContractPermissioningStaticNodesAcceptanceTest extends NodeSmartContractPermissioningAcceptanceTestBase { diff --git a/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java b/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java index a931627c25..11ce3546a8 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/MainnetEVMs.java @@ -34,8 +34,6 @@ import org.hyperledger.besu.evm.operation.AddModOperation; import org.hyperledger.besu.evm.operation.AddOperation; import org.hyperledger.besu.evm.operation.AddressOperation; import org.hyperledger.besu.evm.operation.AndOperation; -import org.hyperledger.besu.evm.operation.AuthCallOperation; -import org.hyperledger.besu.evm.operation.AuthOperation; import org.hyperledger.besu.evm.operation.BalanceOperation; import org.hyperledger.besu.evm.operation.BaseFeeOperation; import org.hyperledger.besu.evm.operation.BlobBaseFeeOperation; @@ -966,9 +964,7 @@ public class MainnetEVMs { final BigInteger chainID) { registerCancunOperations(registry, gasCalculator, chainID); - // EIP-3074 AUTH and AUTHCALL - registry.put(new AuthOperation(gasCalculator)); - registry.put(new AuthCallOperation(gasCalculator)); + // TODO add EOF operations here once PragueEOF is collapsed into Prague } /** diff --git a/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java b/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java index 0cb34bed9d..e01c915510 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java @@ -246,9 +246,6 @@ public class MessageFrame { /** The mark of the undoable collections at the creation of this message frame */ private final long undoMark; - /** mutated by AUTH operation */ - private Address authorizedBy = null; - /** * Builder builder. * @@ -1317,24 +1314,6 @@ public class MessageFrame { return txValues.versionedHashes(); } - /** - * Accessor for address that authorized future AUTHCALLs. - * - * @return the revert reason - */ - public Address getAuthorizedBy() { - return authorizedBy; - } - - /** - * Mutator for address that authorizes future AUTHCALLs, set by AUTH opcode - * - * @param authorizedBy the address that authorizes future AUTHCALLs - */ - public void setAuthorizedBy(final Address authorizedBy) { - this.authorizedBy = authorizedBy; - } - /** Reset. */ public void reset() { maybeUpdatedMemory = Optional.empty(); @@ -1372,7 +1351,9 @@ public class MessageFrame { private Optional> versionedHashes = Optional.empty(); /** Instantiates a new Builder. */ - public Builder() {} + public Builder() { + // constructor added to deal with JavaDoc linting rules. + } /** * The "parent" message frame. When present some fields will be populated from the parent and diff --git a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java index 5b7593b120..2e1728b234 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/GasCalculator.java @@ -224,35 +224,6 @@ public interface GasCalculator { Address contract, boolean accountIsWarm); - /** - * Returns the gas cost for AUTHCALL. - * - * @param frame The current frame - * @param stipend The gas stipend being provided by the CALL caller - * @param inputDataOffset The offset in memory to retrieve the CALL input data - * @param inputDataLength The CALL input data length - * @param outputDataOffset The offset in memory to place the CALL output data - * @param outputDataLength The CALL output data length - * @param transferValue The wei being transferred - * @param invoker The contract calling out on behalf of the authority - * @param invokee The address of the recipient (never null) - * @param accountIsWarm The address of the contract is "warm" as per EIP-2929 - * @return The gas cost for the CALL operation - */ - default long authCallOperationGasCost( - final MessageFrame frame, - final long stipend, - final long inputDataOffset, - final long inputDataLength, - final long outputDataOffset, - final long outputDataLength, - final Wei transferValue, - final Account invoker, - final Address invokee, - final boolean accountIsWarm) { - return 0L; - } - /** * Gets additional call stipend. * @@ -674,18 +645,4 @@ public interface GasCalculator { default long computeExcessBlobGas(final long parentExcessBlobGas, final long blobGasUsed) { return 0L; } - - /** - * Returns the gas cost of validating an auth commitment for an AUTHCALL - * - * @param frame the current frame, with memory to be read from - * @param offset start of memory read - * @param length amount of memory read - * @param authority address to check for warmup - * @return total gas cost for the operation - */ - default long authOperationGasCost( - final MessageFrame frame, final long offset, final long length, final Address authority) { - return 0L; - } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculator.java b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculator.java index 9dde4bdb66..e2789bba33 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculator.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculator.java @@ -16,11 +16,6 @@ package org.hyperledger.besu.evm.gascalculator; import static org.hyperledger.besu.datatypes.Address.BLS12_MAP_FP2_TO_G2; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.evm.account.Account; -import org.hyperledger.besu.evm.frame.MessageFrame; - /** * Gas Calculator for Prague * @@ -32,8 +27,6 @@ import org.hyperledger.besu.evm.frame.MessageFrame; * */ public class PragueGasCalculator extends CancunGasCalculator { - private static final int AUTH_OP_FIXED_FEE = 3100; - private static final long AUTH_CALL_VALUE_TRANSFER_GAS_COST = 6700; /** Instantiates a new Prague Gas Calculator. */ public PragueGasCalculator() { @@ -48,55 +41,4 @@ public class PragueGasCalculator extends CancunGasCalculator { protected PragueGasCalculator(final int maxPrecompile) { super(maxPrecompile); } - - @Override - public long authOperationGasCost( - final MessageFrame frame, final long offset, final long length, final Address authority) { - final long memoryExpansionGasCost = memoryExpansionGasCost(frame, offset, length); - final long accessFee = frame.isAddressWarm(authority) ? 100 : 2600; - final long gasCost = AUTH_OP_FIXED_FEE + memoryExpansionGasCost + accessFee; - return gasCost; - } - - /** - * Returns the gas cost to call another contract on behalf of an authority - * - * @return the gas cost to call another contract on behalf of an authority - */ - @Override - public long authCallOperationGasCost( - final MessageFrame frame, - final long stipend, - final long inputDataOffset, - final long inputDataLength, - final long outputDataOffset, - final long outputDataLength, - final Wei transferValue, - final Account invoker, - final Address invokee, - final boolean accountIsWarm) { - - final long inputDataMemoryExpansionCost = - memoryExpansionGasCost(frame, inputDataOffset, inputDataLength); - final long outputDataMemoryExpansionCost = - memoryExpansionGasCost(frame, outputDataOffset, outputDataLength); - final long memoryExpansionCost = - Math.max(inputDataMemoryExpansionCost, outputDataMemoryExpansionCost); - - final long staticGasCost = getWarmStorageReadCost(); - - long dynamicGasCost = accountIsWarm ? 0 : getColdAccountAccessCost() - getWarmStorageReadCost(); - - if (!transferValue.isZero()) { - dynamicGasCost += AUTH_CALL_VALUE_TRANSFER_GAS_COST; - } - - if ((invoker == null || invoker.isEmpty()) && !transferValue.isZero()) { - dynamicGasCost += newAccountGasCost(); - } - - long cost = staticGasCost + memoryExpansionCost + dynamicGasCost; - - return cost; - } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AuthCallOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AuthCallOperation.java deleted file mode 100644 index 3d4fffffb3..0000000000 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AuthCallOperation.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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.operation; - -import static org.hyperledger.besu.evm.internal.Words.clampedToLong; - -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.internal.Words; - -import org.apache.tuweni.bytes.Bytes32; - -/** Introduced via EIP-3074 to call another contract with a different authorization context. */ -public class AuthCallOperation extends AbstractCallOperation { - - /** - * Instantiates a new AuthCallOperation. - * - * @param gasCalculator a Prague or later gas calculator - */ - public AuthCallOperation(final GasCalculator gasCalculator) { - super(0xF7, "AUTHCALL", 7, 1, gasCalculator); - } - - @Override - protected Address to(final MessageFrame frame) { - return Words.toAddress(frame.getStackItem(1)); - } - - @Override - protected Wei value(final MessageFrame frame) { - return Wei.wrap(frame.getStackItem(2)); - } - - @Override - protected Wei apparentValue(final MessageFrame frame) { - return value(frame); - } - - @Override - protected long inputDataOffset(final MessageFrame frame) { - return clampedToLong(frame.getStackItem(3)); - } - - @Override - protected long inputDataLength(final MessageFrame frame) { - return clampedToLong(frame.getStackItem(4)); - } - - @Override - protected long outputDataOffset(final MessageFrame frame) { - return clampedToLong(frame.getStackItem(5)); - } - - @Override - protected long outputDataLength(final MessageFrame frame) { - return clampedToLong(frame.getStackItem(6)); - } - - @Override - protected Address address(final MessageFrame frame) { - return to(frame); - } - - @Override - protected Address sender(final MessageFrame frame) { - return frame.getAuthorizedBy(); - } - - @Override - public long gasAvailableForChildCall(final MessageFrame frame) { - return gasCalculator().gasAvailableForChildCall(frame, gas(frame), !value(frame).isZero()); - } - - @Override - public OperationResult execute(final MessageFrame frame, final EVM evm) { - if (frame.isStatic() && !value(frame).isZero()) { - return new OperationResult(cost(frame, true), ExceptionalHaltReason.ILLEGAL_STATE_CHANGE); - } else if (frame.getAuthorizedBy() != null) { - return super.execute(frame, evm); - } else { - frame.pushStackItem(Bytes32.ZERO); - return new OperationResult(cost(frame, true), null); - } - } -} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AuthOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AuthOperation.java deleted file mode 100644 index 2de52ab4a5..0000000000 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AuthOperation.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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.operation; - -import static org.hyperledger.besu.evm.internal.Words.clampedToLong; - -import org.hyperledger.besu.crypto.Hash; -import org.hyperledger.besu.crypto.SECPPublicKey; -import org.hyperledger.besu.crypto.SECPSignature; -import org.hyperledger.besu.crypto.SignatureAlgorithm; -import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.account.Account; -import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.GasCalculator; -import org.hyperledger.besu.evm.internal.Words; - -import java.util.Optional; - -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt256; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** The AUTH operation. */ -public class AuthOperation extends AbstractOperation { - - /** The constant MAGIC defined by EIP-3074 */ - public static final byte MAGIC = 0x4; - - private static final Logger LOG = LoggerFactory.getLogger(AuthOperation.class); - - private static final SignatureAlgorithm signatureAlgorithm = - SignatureAlgorithmFactory.getInstance(); - - /** - * Instantiates a new AuthOperation. - * - * @param gasCalculator a Prague or later gas calculator - */ - public AuthOperation(final GasCalculator gasCalculator) { - super(0xF6, "AUTH", 3, 1, gasCalculator); - } - - @Override - public OperationResult execute(final MessageFrame frame, final EVM evm) { - // create authority from stack - Address authority = Words.toAddress(frame.getStackItem(0)); - long offset = clampedToLong(frame.getStackItem(1)); - long length = clampedToLong(frame.getStackItem(2)); - - final long gasCost = - super.gasCalculator().authOperationGasCost(frame, offset, length, authority); - if (frame.getRemainingGas() < gasCost) { - return new OperationResult(gasCost, ExceptionalHaltReason.INSUFFICIENT_GAS); - } - - byte yParity = frame.readMemory(offset, 1).get(0); - Bytes32 r = Bytes32.wrap(frame.readMemory(offset + 1, 32)); - Bytes32 s = Bytes32.wrap(frame.readMemory(offset + 33, 32)); - Bytes32 commit = Bytes32.wrap(frame.readMemory(offset + 65, 32)); - Bytes32 invoker = Bytes32.leftPad(frame.getContractAddress()); - // TODO add test for getting sender nonce when account does not exist - Bytes32 senderNonce = - Bytes32.leftPad( - Bytes.ofUnsignedLong( - Optional.ofNullable(frame.getWorldUpdater().getAccount(authority)) - .map(Account::getNonce) - .orElse(0L))); - if (evm.getChainId().isEmpty()) { - frame.pushStackItem(UInt256.ZERO); - LOG.error("ChainId is not set"); - return new OperationResult(0, null); - } - Bytes authPreImage = - Bytes.concatenate( - Bytes.ofUnsignedShort(MAGIC), evm.getChainId().get(), senderNonce, invoker, commit); - Bytes32 messageHash = Hash.keccak256(authPreImage); - Optional publicKey; - try { - SECPSignature signature = - signatureAlgorithm.createSignature( - r.toUnsignedBigInteger(), s.toUnsignedBigInteger(), yParity); - publicKey = signatureAlgorithm.recoverPublicKeyFromSignature(messageHash, signature); - } catch (IllegalArgumentException e) { - - frame.pushStackItem(UInt256.ZERO); - return new OperationResult(gasCost, null); - } - if (publicKey.isPresent()) { - Address signerAddress = Address.extract(publicKey.get()); - if (signerAddress.equals(authority)) { - frame.setAuthorizedBy(authority); - frame.pushStackItem(UInt256.ONE); - } else { - frame.pushStackItem(UInt256.ZERO); - } - } else { - frame.pushStackItem(UInt256.ZERO); - } - return new OperationResult(gasCost, null); - } -} diff --git a/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculatorTest.java b/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculatorTest.java index 72cacd47cf..c528dab64f 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculatorTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/gascalculator/PragueGasCalculatorTest.java @@ -14,61 +14,17 @@ */ package org.hyperledger.besu.evm.gascalculator; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import static org.assertj.core.api.Assertions.assertThat; import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.evm.account.Account; -import org.hyperledger.besu.evm.account.MutableAccount; -import org.hyperledger.besu.evm.frame.MessageFrame; import org.junit.jupiter.api.Test; -public class PragueGasCalculatorTest { +class PragueGasCalculatorTest { @Test - public void testAuthOperationGasCost() { - PragueGasCalculator pragueGasCalculator = new PragueGasCalculator(); - MessageFrame runningIn = mock(MessageFrame.class); - Address authority = Address.fromHexString("0xdeadbeef"); - when(runningIn.isAddressWarm(authority)).thenReturn(true); - long gasSpent = pragueGasCalculator.authOperationGasCost(runningIn, 0, 97, authority); - assertEquals( - 3100 + 100 + pragueGasCalculator.memoryExpansionGasCost(runningIn, 0, 97), gasSpent); - } - - @Test - public void testAuthCallOperationGasCostWithTransfer() { - PragueGasCalculator pragueGasCalculator = new PragueGasCalculator(); - MessageFrame runningIn = mock(MessageFrame.class); - Account invoker = mock(MutableAccount.class); - when(invoker.getAddress()).thenReturn(Address.fromHexString("0xCafeBabe")); - Address invokee = Address.fromHexString("0xdeadbeef"); - when(runningIn.isAddressWarm(invokee)).thenReturn(true); - long gasSpentInAuthCall = - pragueGasCalculator.authCallOperationGasCost( - runningIn, 63, 0, 97, 100, 97, Wei.ONE, invoker, invokee, true); - long gasSpentInCall = - pragueGasCalculator.callOperationGasCost( - runningIn, 63, 0, 97, 100, 97, Wei.ONE, invoker, invokee, true); - assertEquals(gasSpentInCall - 2300, gasSpentInAuthCall); - } - - @Test - public void testAuthCallOperationGasCostNoTransfer() { - PragueGasCalculator pragueGasCalculator = new PragueGasCalculator(); - MessageFrame runningIn = mock(MessageFrame.class); - Account invoker = mock(MutableAccount.class); - when(invoker.getAddress()).thenReturn(Address.fromHexString("0xCafeBabe")); - Address invokee = Address.fromHexString("0xdeadbeef"); - when(runningIn.isAddressWarm(invokee)).thenReturn(true); - long gasSpentInAuthCall = - pragueGasCalculator.authCallOperationGasCost( - runningIn, 63, 0, 97, 100, 97, Wei.ZERO, invoker, invokee, true); - long gasSpentInCall = - pragueGasCalculator.callOperationGasCost( - runningIn, 63, 0, 97, 100, 97, Wei.ZERO, invoker, invokee, true); - assertEquals(gasSpentInCall, gasSpentInAuthCall); + void testPrecompileSize() { + PragueGasCalculator subject = new PragueGasCalculator(); + assertThat(subject.isPrecompile(Address.precompiled(0x14))).isFalse(); + assertThat(subject.isPrecompile(Address.BLS12_MAP_FP2_TO_G2)).isTrue(); } } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/operations/AuthOperationTest.java b/evm/src/test/java/org/hyperledger/besu/evm/operations/AuthOperationTest.java deleted file mode 100644 index be76e885b2..0000000000 --- a/evm/src/test/java/org/hyperledger/besu/evm/operations/AuthOperationTest.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * 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.operations; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import org.hyperledger.besu.crypto.Hash; -import org.hyperledger.besu.crypto.KeyPair; -import org.hyperledger.besu.crypto.SECPSignature; -import org.hyperledger.besu.crypto.SignatureAlgorithm; -import org.hyperledger.besu.crypto.SignatureAlgorithmFactory; -import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.evm.EVM; -import org.hyperledger.besu.evm.account.MutableAccount; -import org.hyperledger.besu.evm.frame.MessageFrame; -import org.hyperledger.besu.evm.gascalculator.PragueGasCalculator; -import org.hyperledger.besu.evm.operation.AuthOperation; -import org.hyperledger.besu.evm.worldstate.WorldUpdater; - -import java.util.Optional; - -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; -import org.apache.tuweni.units.bigints.UInt256; -import org.junit.jupiter.api.Test; - -public class AuthOperationTest { - - @Test - public void testAuthOperation() { - SignatureAlgorithm algo = SignatureAlgorithmFactory.getInstance(); - KeyPair keys = algo.generateKeyPair(); - Address authingAddress = Address.extract(keys.getPublicKey()); - EVM fakeEVM = mock(EVM.class); - - Optional chainId = Optional.of(Bytes.of(1)); - when(fakeEVM.getChainId()).thenReturn(chainId); - long senderNonce = 0; - Address invokerAddress = Address.fromHexString("0xdeadbeef"); - Bytes32 invoker = Bytes32.leftPad(invokerAddress); - Bytes32 contractCommitment = Bytes32.leftPad(Bytes.fromHexString("0x1234")); - Bytes authPreImage = - Bytes.concatenate( - Bytes.ofUnsignedShort(AuthOperation.MAGIC), - chainId.get(), - Bytes32.leftPad(Bytes.ofUnsignedLong(senderNonce)), - invoker, - contractCommitment); - Bytes32 messageHash = Hash.keccak256(authPreImage); - SECPSignature signature = algo.sign(messageHash, keys); - - MessageFrame frame = mock(MessageFrame.class); - when(frame.getContractAddress()).thenReturn(invokerAddress); - MutableAccount authingAccount = mock(MutableAccount.class); - when(authingAccount.getAddress()).thenReturn(authingAddress); - when(authingAccount.getNonce()).thenReturn(senderNonce); - when(frame.getRemainingGas()).thenReturn(1000000L); - WorldUpdater state = mock(WorldUpdater.class); - - when(state.getAccount(authingAddress)).thenReturn(authingAccount); - - when(frame.getWorldUpdater()).thenReturn(state); - - when(frame.getSenderAddress()).thenReturn(authingAddress); - when(state.getSenderAccount(frame)).thenReturn(authingAccount); - when(frame.getStackItem(0)).thenReturn(authingAddress); - when(frame.getStackItem(1)).thenReturn(Bytes.of(0)); - when(frame.getStackItem(2)).thenReturn(Bytes.of(97)); - Bytes encodedSignature = signature.encodedBytes(); - when(frame.readMemory(0, 1)).thenReturn(encodedSignature.slice(64, 1)); - when(frame.readMemory(1, 32)).thenReturn(Bytes32.wrap(encodedSignature.slice(0, 32).toArray())); - when(frame.readMemory(33, 32)) - .thenReturn(Bytes32.wrap(encodedSignature.slice(32, 32).toArray())); - when(frame.readMemory(65, 32)).thenReturn(contractCommitment); - - AuthOperation authOperation = new AuthOperation(new PragueGasCalculator()); - authOperation.execute(frame, fakeEVM); - verify(frame).setAuthorizedBy(authingAddress); - verify(frame).pushStackItem(UInt256.ONE); - } - - @Test - public void testAuthOperationNegative() { - SignatureAlgorithm algo = SignatureAlgorithmFactory.getInstance(); - KeyPair keys = algo.generateKeyPair(); - Address authingAddress = Address.extract(keys.getPublicKey()); - EVM fakeEVM = mock(EVM.class); - - Optional chainId = Optional.of(Bytes.of(1)); - when(fakeEVM.getChainId()).thenReturn(chainId); - long senderNonce = 0; - Address invokerAddress = Address.fromHexString("0xdeadbeef"); - Bytes32 invoker = Bytes32.leftPad(invokerAddress); - Bytes32 contractCommitment = Bytes32.leftPad(Bytes.fromHexString("0x1234")); - Bytes authPreImage = - Bytes.concatenate( - Bytes.ofUnsignedShort(AuthOperation.MAGIC), - chainId.get(), - Bytes32.leftPad(Bytes.ofUnsignedLong(senderNonce)), - invoker, - contractCommitment); - Bytes32 messageHash = Hash.keccak256(authPreImage); - - // Generate a new key pair to create an incorrect signature - KeyPair wrongKeys = algo.generateKeyPair(); - SECPSignature wrongSignature = algo.sign(messageHash, wrongKeys); - - MessageFrame frame = mock(MessageFrame.class); - when(frame.getRemainingGas()).thenReturn(1000000L); - when(frame.getContractAddress()).thenReturn(invokerAddress); - MutableAccount authingAccount = mock(MutableAccount.class); - when(authingAccount.getAddress()).thenReturn(authingAddress); - when(authingAccount.getNonce()).thenReturn(senderNonce); - - WorldUpdater state = mock(WorldUpdater.class); - - when(state.getAccount(authingAddress)).thenReturn(authingAccount); - - when(frame.getWorldUpdater()).thenReturn(state); - - when(frame.getSenderAddress()).thenReturn(authingAddress); - when(state.getSenderAccount(frame)).thenReturn(authingAccount); - when(frame.getStackItem(0)).thenReturn(authingAddress); - when(frame.getStackItem(1)).thenReturn(Bytes.of(0)); - when(frame.getStackItem(2)).thenReturn(Bytes.of(97)); - Bytes encodedSignature = wrongSignature.encodedBytes(); // Use the wrong signature - when(frame.readMemory(0, 1)).thenReturn(encodedSignature.slice(64, 1)); - when(frame.readMemory(1, 32)).thenReturn(Bytes32.wrap(encodedSignature.slice(0, 32).toArray())); - when(frame.readMemory(33, 32)) - .thenReturn(Bytes32.wrap(encodedSignature.slice(32, 32).toArray())); - when(frame.readMemory(65, 32)).thenReturn(contractCommitment); - - AuthOperation authOperation = new AuthOperation(new PragueGasCalculator()); - authOperation.execute(frame, fakeEVM); - verify(frame, never()).setAuthorizedBy(authingAddress); // The address should not be authorized - verify(frame).pushStackItem(UInt256.ZERO); // The stack should contain UInt256.ZERO - } -} diff --git a/evm/src/test/java/org/hyperledger/besu/evm/toy/ToyAccount.java b/evm/src/test/java/org/hyperledger/besu/evm/toy/ToyAccount.java index 8548a50d8e..4dd3018a55 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/toy/ToyAccount.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/toy/ToyAccount.java @@ -171,7 +171,10 @@ public class ToyAccount implements MutableAccount { */ @Override public boolean isStorageEmpty() { - return storage.isEmpty(); + if (storage.isEmpty()) { + return parent == null || parent.isStorageEmpty(); + } + return false; } @Override