Increment private nonce even if transaction failed. (#6593)

Increment private nonce even if transaction failed

Signed-off-by: George Tebrean <george@web3labs.com>
Signed-off-by: stefan.pingel@consensys.net <stefan.pingel@consensys.net>
Co-authored-by: stefan.pingel@consensys.net <stefan.pingel@consensys.net>
Co-authored-by: Stefan Pingel <16143240+pinges@users.noreply.github.com>
pull/7321/head
George Tebrean 4 months ago committed by GitHub
parent 33f2ae2726
commit 5660ebc1ce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 3
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/ProcessBesuNodeRunner.java
  3. 4
      acceptance-tests/dsl/src/main/java/org/hyperledger/besu/tests/acceptance/dsl/node/configuration/BesuNodeFactory.java
  4. 1
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyAcceptanceTest.java
  5. 241
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyPrivateNonceIncrementingTest.java
  6. 1
      acceptance-tests/tests/src/test/java/org/hyperledger/besu/tests/acceptance/privacy/multitenancy/MultiTenancyValidationFailAcceptanceTest.java
  7. 9
      besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
  8. 1
      besu/src/test/resources/everything_config.toml
  9. 1
      ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractIntegrationTest.java
  10. 18
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/PrivacyParameters.java
  11. 7
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/FlexiblePrivacyPrecompiledContract.java
  12. 29
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContract.java
  13. 6
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/FlexiblePrivacyPrecompiledContractTest.java
  14. 4
      ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/precompiles/privacy/PrivacyPrecompiledContractTest.java

@ -34,6 +34,7 @@
- Promote experimental `besu storage x-trie-log` subcommand to production-ready [#7278](https://github.com/hyperledger/besu/pull/7278)
- Enhanced BFT round-change diagnostics [#7271](https://github.com/hyperledger/besu/pull/7271)
- `--Xsnapsync-bft-enabled` option enables experimental support for snap sync with IBFT/QBFT permissioned Bonsai-DB chains [#7140](https://github.com/hyperledger/besu/pull/7140)
- `privacy-nonce-always-increments` option enables private transactions to always increment the nonce, even if the transaction is invalid [#6593](https://github.com/hyperledger/besu/pull/6593)
### Bug fixes
- Validation errors ignored in accounts-allowlist and empty list [#7138](https://github.com/hyperledger/besu/issues/7138)

@ -166,6 +166,9 @@ public class ProcessBesuNodeRunner implements BesuNodeRunner {
if (node.getPrivacyParameters().isPrivacyPluginEnabled()) {
params.add("--Xprivacy-plugin-enabled");
}
if (node.getPrivacyParameters().isPrivateNonceAlwaysIncrementsEnabled()) {
params.add("privacy-nonce-always-increments");
}
}
if (!node.getBootnodes().isEmpty()) {

@ -287,7 +287,8 @@ public class BesuNodeFactory {
final String enclaveUrl,
final String authFile,
final String privTransactionSigningKey,
final boolean enableFlexiblePrivacy)
final boolean enableFlexiblePrivacy,
final boolean enablePrivateNonceAlwaysIncrements)
throws IOException, URISyntaxException {
final PrivacyParameters.Builder privacyParametersBuilder = new PrivacyParameters.Builder();
final PrivacyParameters privacyParameters =
@ -298,6 +299,7 @@ public class BesuNodeFactory {
.setStorageProvider(new InMemoryPrivacyStorageProvider())
.setEnclaveFactory(new EnclaveFactory(Vertx.vertx()))
.setEnclaveUrl(URI.create(enclaveUrl))
.setPrivateNonceAlwaysIncrementsEnabled(enablePrivateNonceAlwaysIncrements)
.setPrivateKeyPath(
Paths.get(ClassLoader.getSystemResource(privTransactionSigningKey).toURI()))
.build();

@ -104,6 +104,7 @@ public class MultiTenancyAcceptanceTest extends AcceptanceTestBase {
"http://127.0.0.1:" + wireMockRule.port(),
"authentication/auth_priv.toml",
"authentication/auth_priv_key",
false,
false);
multiTenancyCluster.start(node);
final String token =

@ -0,0 +1,241 @@
/*
* 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.tests.acceptance.privacy.multitenancy;
import static com.github.tomakehurst.wiremock.client.WireMock.ok;
import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
import static java.nio.charset.StandardCharsets.UTF_8;
import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.crypto.SignatureAlgorithm;
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.Wei;
import org.hyperledger.besu.enclave.types.PrivacyGroup;
import org.hyperledger.besu.enclave.types.ReceiveResponse;
import org.hyperledger.besu.enclave.types.SendResponse;
import org.hyperledger.besu.ethereum.privacy.PrivateTransaction;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
import org.hyperledger.besu.plugin.data.Restriction;
import org.hyperledger.besu.tests.acceptance.dsl.AcceptanceTestBase;
import org.hyperledger.besu.tests.acceptance.dsl.node.BesuNode;
import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.Cluster;
import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfiguration;
import org.hyperledger.besu.tests.acceptance.dsl.node.cluster.ClusterConfigurationBuilder;
import java.math.BigInteger;
import java.util.List;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import org.apache.tuweni.bytes.Bytes;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
public class MultiTenancyPrivateNonceIncrementingTest extends AcceptanceTestBase {
private BesuNode node;
private final ObjectMapper mapper = new ObjectMapper();
private Cluster multiTenancyCluster;
private static final Supplier<SignatureAlgorithm> SIGNATURE_ALGORITHM =
Suppliers.memoize(SignatureAlgorithmFactory::getInstance);
private static final KeyPair TEST_KEY =
SIGNATURE_ALGORITHM
.get()
.createKeyPair(
SIGNATURE_ALGORITHM
.get()
.createPrivateKey(
new BigInteger(
"853d7f0010fd86d0d7811c1f9d968ea89a24484a8127b4a483ddf5d2cfec766d", 16)));
private static final String PRIVACY_GROUP_ID = "B1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=";
private static final String PARTICIPANT_ENCLAVE_KEY0 =
"A1aVtMxLCUHmBVHXoZzzBgPbW/wj5axDpW9X8l91SGo=";
private static final String PARTICIPANT_ENCLAVE_KEY1 =
"sgFkVOyFndZe/5SAZJO5UYbrl7pezHetveriBBWWnE8=";
private final Address senderAddress =
Address.wrap(Bytes.fromHexString(accounts.getPrimaryBenefactor().getAddress()));
@Rule public WireMockRule wireMockRule = new WireMockRule(options().dynamicPort());
@Before
public void setUp() throws Exception {
final ClusterConfiguration clusterConfiguration =
new ClusterConfigurationBuilder().awaitPeerDiscovery(false).build();
multiTenancyCluster = new Cluster(clusterConfiguration, net);
node =
besu.createNodeWithMultiTenantedPrivacy(
"node1",
"http://127.0.0.1:" + wireMockRule.port(),
"authentication/auth_priv.toml",
"authentication/auth_priv_key",
false,
true);
multiTenancyCluster.start(node);
final String token =
node.execute(permissioningTransactions.createSuccessfulLogin("user", "pegasys"));
node.useAuthenticationTokenInHeaderForJsonRpc(token);
}
@After
public void tearDown() {
multiTenancyCluster.close();
}
@Test
public void validateUnsuccessfulPrivateTransactionsNonceIncrementation()
throws JsonProcessingException {
executePrivateFailingTransaction(0, 0, 1);
executePrivateValidTransaction(1, 1, 2);
executePrivateFailingTransaction(2, 2, 3);
executePrivateFailingTransaction(3, 3, 4);
executePrivateValidTransaction(4, 4, 5);
}
private void executePrivateValidTransaction(
final int nonce,
final int expectedTransactionCountBeforeExecution,
final int expectedTransactionCountAfterExecution)
throws JsonProcessingException {
final PrivateTransaction validSignedPrivateTransaction =
getValidSignedPrivateTransaction(senderAddress, nonce);
final String accountAddress = validSignedPrivateTransaction.getSender().toHexString();
final BytesValueRLPOutput rlpOutput = getRLPOutput(validSignedPrivateTransaction);
processEnclaveStub(validSignedPrivateTransaction);
node.verify(
priv.getTransactionCount(
accountAddress, PRIVACY_GROUP_ID, expectedTransactionCountBeforeExecution));
final Hash transactionReceipt =
node.execute(privacyTransactions.sendRawTransaction(rlpOutput.encoded().toHexString()));
node.verify(priv.getSuccessfulTransactionReceipt(transactionReceipt));
node.verify(
priv.getTransactionCount(
accountAddress, PRIVACY_GROUP_ID, expectedTransactionCountAfterExecution));
}
private void executePrivateFailingTransaction(
final int nonce,
final int expectedTransactionCountBeforeExecution,
final int expectedTransactionCountAfterExecution)
throws JsonProcessingException {
final PrivateTransaction invalidSignedPrivateTransaction =
getInvalidSignedPrivateTransaction(senderAddress, nonce);
final String accountAddress = invalidSignedPrivateTransaction.getSender().toHexString();
final BytesValueRLPOutput invalidTxRlp = getRLPOutput(invalidSignedPrivateTransaction);
processEnclaveStub(invalidSignedPrivateTransaction);
node.verify(
priv.getTransactionCount(
accountAddress, PRIVACY_GROUP_ID, expectedTransactionCountBeforeExecution));
final Hash invalidTransactionReceipt =
node.execute(privacyTransactions.sendRawTransaction(invalidTxRlp.encoded().toHexString()));
node.verify(priv.getFailedTransactionReceipt(invalidTransactionReceipt));
node.verify(
priv.getTransactionCount(
accountAddress, PRIVACY_GROUP_ID, expectedTransactionCountAfterExecution));
}
private void processEnclaveStub(final PrivateTransaction validSignedPrivateTransaction)
throws JsonProcessingException {
retrievePrivacyGroupEnclaveStub();
sendEnclaveStub();
receiveEnclaveStub(validSignedPrivateTransaction);
}
private void retrievePrivacyGroupEnclaveStub() throws JsonProcessingException {
final String retrieveGroupResponse =
mapper.writeValueAsString(
createPrivacyGroup(
List.of(PARTICIPANT_ENCLAVE_KEY0, PARTICIPANT_ENCLAVE_KEY1),
PrivacyGroup.Type.PANTHEON));
stubFor(post("/retrievePrivacyGroup").willReturn(ok(retrieveGroupResponse)));
}
private void sendEnclaveStub() throws JsonProcessingException {
final String sendResponse =
mapper.writeValueAsString(new SendResponse(PARTICIPANT_ENCLAVE_KEY1));
stubFor(post("/send").willReturn(ok(sendResponse)));
}
private void receiveEnclaveStub(final PrivateTransaction privTx) throws JsonProcessingException {
final BytesValueRLPOutput rlpOutput = getRLPOutput(privTx);
final String senderKey = privTx.getPrivateFrom().toBase64String();
final String receiveResponse =
mapper.writeValueAsString(
new ReceiveResponse(
rlpOutput.encoded().toBase64String().getBytes(UTF_8), PRIVACY_GROUP_ID, senderKey));
stubFor(post("/receive").willReturn(ok(receiveResponse)));
}
private BytesValueRLPOutput getRLPOutput(final PrivateTransaction privateTransaction) {
final BytesValueRLPOutput bvrlpo = new BytesValueRLPOutput();
privateTransaction.writeTo(bvrlpo);
return bvrlpo;
}
private PrivacyGroup createPrivacyGroup(
final List<String> groupMembers, final PrivacyGroup.Type groupType) {
return new PrivacyGroup(PRIVACY_GROUP_ID, groupType, "test", "testGroup", groupMembers);
}
private static PrivateTransaction getInvalidSignedPrivateTransaction(
final Address senderAddress, final int nonce) {
return PrivateTransaction.builder()
.nonce(nonce)
.gasPrice(Wei.ZERO)
.gasLimit(3000000)
.to(null)
.value(Wei.ZERO)
.payload(Bytes.fromHexString("0x1234"))
.sender(senderAddress)
.chainId(BigInteger.valueOf(1337))
.privateFrom(Bytes.fromBase64String(PARTICIPANT_ENCLAVE_KEY0))
.restriction(Restriction.RESTRICTED)
.privacyGroupId(Bytes.fromBase64String(PRIVACY_GROUP_ID))
.signAndBuild(TEST_KEY);
}
private static PrivateTransaction getValidSignedPrivateTransaction(
final Address senderAddress, final int nonce) {
return PrivateTransaction.builder()
.nonce(nonce)
.gasPrice(Wei.ZERO)
.gasLimit(3000000)
.to(null)
.value(Wei.ZERO)
.payload(Bytes.wrap(new byte[] {}))
.sender(senderAddress)
.chainId(BigInteger.valueOf(1337))
.privateFrom(Bytes.fromBase64String(PARTICIPANT_ENCLAVE_KEY0))
.restriction(Restriction.RESTRICTED)
.privacyGroupId(Bytes.fromBase64String(PRIVACY_GROUP_ID))
.signAndBuild(TEST_KEY);
}
}

@ -78,6 +78,7 @@ public class MultiTenancyValidationFailAcceptanceTest extends AcceptanceTestBase
"http://127.0.0.1:" + wireMockRule.port(),
"authentication/auth_priv.toml",
"authentication/auth_priv_key",
false,
false);
multiTenancyCluster.start(node);

@ -715,6 +715,13 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
names = {"--privacy-flexible-groups-enabled"},
description = "Enable flexible privacy groups (default: ${DEFAULT-VALUE})")
private final Boolean isFlexiblePrivacyGroupsEnabled = false;
@Option(
names = {"--privacy-nonce-always-increments"},
description =
"Enable private nonce "
+ "incrementation even if the transaction didn't succeeded (default: ${DEFAULT-VALUE})")
private final Boolean isPrivateNonceAlwaysIncrementsEnabled = false;
}
// Metrics Option Group
@ -2062,6 +2069,8 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
privacyOptionGroup.isFlexiblePrivacyGroupsEnabled);
privacyParametersBuilder.setPrivacyPluginEnabled(
unstablePrivacyPluginOptions.isPrivacyPluginEnabled());
privacyParametersBuilder.setPrivateNonceAlwaysIncrementsEnabled(
privacyOptionGroup.isPrivateNonceAlwaysIncrementsEnabled);
final boolean hasPrivacyPublicKey = privacyOptionGroup.privacyPublicKeyFile != null;

@ -172,6 +172,7 @@ privacy-multi-tenancy-enabled=true
privacy-marker-transaction-signing-key-file="./signerKey"
privacy-enable-database-migration=false
privacy-flexible-groups-enabled=false
privacy-nonce-always-increments=false
# Transaction Pool
tx-pool="layered"

@ -205,6 +205,7 @@ public class PrivacyPrecompiledContractIntegrationTest {
new PrivateStateRootResolver(privateStateStorage),
new PrivateStateGenesisAllocator(
false, (privacyGroupId, blockNumber) -> Collections::emptyList),
false,
"IntegrationTest");
privacyPrecompiledContract.setPrivateTransactionProcessor(mockPrivateTxProcessor());

@ -77,6 +77,7 @@ public class PrivacyParameters {
private PrivateStateRootResolver privateStateRootResolver;
private PrivateWorldStateReader privateWorldStateReader;
private PrivacyPluginService privacyPluginService;
private boolean privateNonceAlwaysIncrementsEnabled;
public Address getPrivacyAddress() {
if (isPrivacyPluginEnabled()) {
@ -228,6 +229,15 @@ public class PrivacyParameters {
}
}
public boolean isPrivateNonceAlwaysIncrementsEnabled() {
return privateNonceAlwaysIncrementsEnabled;
}
public void setPrivateNonceAlwaysIncrementsEnabled(
final boolean privateNonceAlwaysIncrementsEnabled) {
this.privateNonceAlwaysIncrementsEnabled = privateNonceAlwaysIncrementsEnabled;
}
@Override
public String toString() {
return "PrivacyParameters{"
@ -263,6 +273,7 @@ public class PrivacyParameters {
private boolean flexiblePrivacyGroupsEnabled;
private boolean privacyPluginEnabled;
private PrivacyPluginService privacyPluginService;
private boolean privateNonceAlwaysIncrementsEnabled;
public Builder setEnclaveUrl(final URI enclaveUrl) {
this.enclaveUrl = enclaveUrl;
@ -314,6 +325,12 @@ public class PrivacyParameters {
return this;
}
public Builder setPrivateNonceAlwaysIncrementsEnabled(
final boolean isPrivateNonceAlwaysIncrementsEnabled) {
this.privateNonceAlwaysIncrementsEnabled = isPrivateNonceAlwaysIncrementsEnabled;
return this;
}
public Builder setPrivacyPluginEnabled(final boolean privacyPluginEnabled) {
this.privacyPluginEnabled = privacyPluginEnabled;
return this;
@ -382,6 +399,7 @@ public class PrivacyParameters {
config.setMultiTenancyEnabled(multiTenancyEnabled);
config.setFlexiblePrivacyGroupsEnabled(flexiblePrivacyGroupsEnabled);
config.setPrivacyPluginEnabled(privacyPluginEnabled);
config.setPrivateNonceAlwaysIncrementsEnabled(privateNonceAlwaysIncrementsEnabled);
return config;
}
}

@ -70,13 +70,15 @@ public class FlexiblePrivacyPrecompiledContract extends PrivacyPrecompiledContra
final Enclave enclave,
final WorldStateArchive worldStateArchive,
final PrivateStateRootResolver privateStateRootResolver,
final PrivateStateGenesisAllocator privateStateGenesisAllocator) {
final PrivateStateGenesisAllocator privateStateGenesisAllocator,
final boolean alwaysIncrementPrivateNonce) {
super(
gasCalculator,
enclave,
worldStateArchive,
privateStateRootResolver,
privateStateGenesisAllocator,
alwaysIncrementPrivateNonce,
"FlexiblePrivacy");
}
@ -87,7 +89,8 @@ public class FlexiblePrivacyPrecompiledContract extends PrivacyPrecompiledContra
privacyParameters.getEnclave(),
privacyParameters.getPrivateWorldStateArchive(),
privacyParameters.getPrivateStateRootResolver(),
privacyParameters.getPrivateStateGenesisAllocator());
privacyParameters.getPrivateStateGenesisAllocator(),
privacyParameters.isPrivateNonceAlwaysIncrementsEnabled());
}
public long addPrivateTransactionObserver(final PrivateTransactionObserver observer) {

@ -19,6 +19,7 @@ import static org.hyperledger.besu.ethereum.mainnet.PrivateStateUtils.KEY_PRIVAT
import static org.hyperledger.besu.ethereum.mainnet.PrivateStateUtils.KEY_TRANSACTION_HASH;
import static org.hyperledger.besu.ethereum.privacy.PrivateStateRootResolver.EMPTY_ROOT_HASH;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.enclave.Enclave;
import org.hyperledger.besu.enclave.EnclaveClientException;
@ -40,6 +41,7 @@ import org.hyperledger.besu.ethereum.privacy.storage.PrivateTransactionMetadata;
import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPInput;
import org.hyperledger.besu.ethereum.worldstate.WorldStateArchive;
import org.hyperledger.besu.evm.account.MutableAccount;
import org.hyperledger.besu.evm.frame.BlockValues;
import org.hyperledger.besu.evm.frame.MessageFrame;
import org.hyperledger.besu.evm.gascalculator.GasCalculator;
@ -61,6 +63,7 @@ public class PrivacyPrecompiledContract extends AbstractPrecompiledContract {
final WorldStateArchive privateWorldStateArchive;
final PrivateStateRootResolver privateStateRootResolver;
private final PrivateStateGenesisAllocator privateStateGenesisAllocator;
final boolean alwaysIncrementPrivateNonce;
PrivateTransactionProcessor privateTransactionProcessor;
private static final Logger LOG = LoggerFactory.getLogger(PrivacyPrecompiledContract.class);
@ -79,6 +82,7 @@ public class PrivacyPrecompiledContract extends AbstractPrecompiledContract {
privacyParameters.getPrivateWorldStateArchive(),
privacyParameters.getPrivateStateRootResolver(),
privacyParameters.getPrivateStateGenesisAllocator(),
privacyParameters.isPrivateNonceAlwaysIncrementsEnabled(),
name);
}
@ -88,12 +92,14 @@ public class PrivacyPrecompiledContract extends AbstractPrecompiledContract {
final WorldStateArchive worldStateArchive,
final PrivateStateRootResolver privateStateRootResolver,
final PrivateStateGenesisAllocator privateStateGenesisAllocator,
final boolean alwaysIncrementPrivateNonce,
final String name) {
super(name, gasCalculator);
this.enclave = enclave;
this.privateWorldStateArchive = worldStateArchive;
this.privateStateRootResolver = privateStateRootResolver;
this.privateStateGenesisAllocator = privateStateGenesisAllocator;
this.alwaysIncrementPrivateNonce = alwaysIncrementPrivateNonce;
}
public void setPrivateTransactionProcessor(
@ -181,18 +187,31 @@ public class PrivacyPrecompiledContract extends AbstractPrecompiledContract {
processPrivateTransaction(
messageFrame, privateTransaction, privacyGroupId, privateWorldStateUpdater);
if (result.isInvalid() || !result.isSuccessful()) {
final Boolean isPersistingPrivateState =
messageFrame.getContextVariable(KEY_IS_PERSISTING_PRIVATE_STATE, false);
if (!result.isSuccessful()) {
LOG.error(
"Failed to process private transaction {}: {}",
pmtHash,
result.getValidationResult().getErrorMessage());
privateMetadataUpdater.putTransactionReceipt(pmtHash, new PrivateTransactionReceipt(result));
if (isPersistingPrivateState && alwaysIncrementPrivateNonce) {
final Address senderAddress = privateTransaction.getSender();
final MutableAccount senderAccount = privateWorldStateUpdater.getOrCreate(senderAddress);
senderAccount.incrementNonce();
// we can safely commit the updater here, because it is only changed if the transaction is
// successful,
// so we can be sure that the only change is the incremented nonce
privateWorldStateUpdater.commit();
disposablePrivateState.persist(null);
storePrivateMetadata(
pmtHash, privacyGroupId, disposablePrivateState, privateMetadataUpdater, result);
}
return NO_RESULT;
}
if (messageFrame.getContextVariable(KEY_IS_PERSISTING_PRIVATE_STATE, false)) {
if (isPersistingPrivateState) {
privateWorldStateUpdater.commit();
disposablePrivateState.persist(null);

@ -383,7 +383,8 @@ public class FlexiblePrivacyPrecompiledContractTest {
enclave,
worldStateArchive,
privateStateRootResolver,
privateStateGenesisAllocator);
privateStateGenesisAllocator,
false);
contract.setPrivateTransactionProcessor(
mockPrivateTxProcessor(
@ -427,6 +428,7 @@ public class FlexiblePrivacyPrecompiledContractTest {
enclave,
worldStateArchive,
privateStateRootResolver,
privateStateGenesisAllocator);
privateStateGenesisAllocator,
false);
}
}

@ -302,6 +302,7 @@ public class PrivacyPrecompiledContractTest {
worldStateArchive,
privateStateRootResolver,
privateStateGenesisAllocator,
false,
"RestrictedPrivacyTest");
contract.setPrivateTransactionProcessor(
@ -328,7 +329,7 @@ public class PrivacyPrecompiledContractTest {
@Test
public void testSimulatedPublicTransactionIsSkipped() {
final PrivacyPrecompiledContract emptyContract =
new PrivacyPrecompiledContract(null, null, null, null, null, null);
new PrivacyPrecompiledContract(null, null, null, null, null, false, null);
// A simulated public transaction doesn't contain a PrivateMetadataUpdater
final MessageFrame frame = mock(MessageFrame.class);
@ -355,6 +356,7 @@ public class PrivacyPrecompiledContractTest {
worldStateArchive,
privateStateRootResolver,
privateStateGenesisAllocator,
false,
"PrivacyTests");
}
}

Loading…
Cancel
Save