From 6c4703227f58a63fd4fcbcedcdad98a42152a5a9 Mon Sep 17 00:00:00 2001 From: Mustafa Uzun Date: Mon, 6 Jan 2025 15:42:37 +0200 Subject: [PATCH 01/11] refactor: enhance migration testing tool Signed-off-by: Mustafa Uzun --- .../migration/MigrationTestingToolMain.java | 9 +++++++- .../migration/MigrationTestingToolState.java | 22 ++++++++++++++++++- .../demo/migration/TransactionUtils.java | 14 +++++++++++- .../swirlds/platform/system/SwirldMain.java | 14 +++++++++++- 4 files changed, 55 insertions(+), 4 deletions(-) diff --git a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolMain.java b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolMain.java index 4c87694f44a4..19273ea8b236 100644 --- a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolMain.java +++ b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolMain.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2024 Hedera Hashgraph, LLC + * Copyright (C) 2022-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,8 @@ import static com.swirlds.platform.test.fixtures.state.FakeMerkleStateLifecycles.registerMerkleStateRootClassIds; import com.hedera.hapi.node.state.roster.RosterEntry; +import com.hedera.hapi.platform.event.StateSignatureTransaction; +import com.hedera.pbj.runtime.io.buffer.Bytes; import com.swirlds.common.constructable.ClassConstructorPair; import com.swirlds.common.constructable.ConstructableRegistry; import com.swirlds.common.constructable.ConstructableRegistryException; @@ -207,4 +209,9 @@ public PlatformMerkleStateRoot newMerkleStateRoot() { public BasicSoftwareVersion getSoftwareVersion() { return softwareVersion; } + + @Override + public Bytes encodeSystemTransaction(@NonNull StateSignatureTransaction transaction) { + return StateSignatureTransaction.PROTOBUF.toBytes(transaction); + } } diff --git a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolState.java b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolState.java index 7ec5c81b4690..f64ce5e0a5ce 100644 --- a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolState.java +++ b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolState.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2024 Hedera Hashgraph, LLC + * Copyright (C) 2022-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package com.swirlds.demo.migration; import static com.swirlds.demo.migration.MigrationTestingToolMain.PREVIOUS_SOFTWARE_VERSION; +import static com.swirlds.demo.migration.TransactionUtils.isSystemTransaction; import static com.swirlds.logging.legacy.LogMarker.STARTUP; import static com.swirlds.platform.test.fixtures.state.FakeMerkleStateLifecycles.FAKE_MERKLE_STATE_LIFECYCLES; @@ -47,6 +48,7 @@ import com.swirlds.platform.system.SoftwareVersion; import com.swirlds.platform.system.address.AddressBook; import com.swirlds.platform.system.events.ConsensusEvent; +import com.swirlds.platform.system.events.Event; import com.swirlds.platform.system.transaction.ConsensusTransaction; import com.swirlds.virtualmap.VirtualMap; import com.swirlds.virtualmap.datasource.VirtualDataSourceBuilder; @@ -278,6 +280,18 @@ public void init( } } + @Override + public void preHandle( + @NonNull Event event, + @NonNull Consumer> stateSignatureTransaction) { + event.forEachTransaction(transaction -> { + if (!transaction.isSystem() && isSystemTransaction(transaction.getApplicationTransaction())) { + stateSignatureTransaction.accept( + new ScopedSystemTransaction(event.getCreatorId(), event.getSoftwareVersion(), transaction)); + } + }); + } + /** * {@inheritDoc} */ @@ -295,6 +309,12 @@ public void handleConsensusRound( if (trans.isSystem()) { continue; } + if (isSystemTransaction(trans.getApplicationTransaction())) { + stateSignatureTransaction.accept( + new ScopedSystemTransaction(event.getCreatorId(), event.getSoftwareVersion(), event)); + return; + } + final MigrationTestingToolTransaction mTrans = TransactionUtils.parseTransaction(trans.getApplicationTransaction()); mTrans.applyTo(this); diff --git a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/TransactionUtils.java b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/TransactionUtils.java index 850351c9ba14..8459438e508c 100644 --- a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/TransactionUtils.java +++ b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/TransactionUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,4 +38,16 @@ public class TransactionUtils { throw new UncheckedIOException("Could not parse transaction kind:%s".formatted(bytes.toHex()), e); } } + + public static boolean isSystemTransaction(@NonNull final Bytes bytes) { + final SerializableDataInputStream in = new SerializableDataInputStream(bytes.toInputStream()); + + try { + MigrationTestingToolTransaction transaction = + in.readSerializable(false, MigrationTestingToolTransaction::new); + return false; + } catch (final IOException e) { + return true; + } + } } diff --git a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/system/SwirldMain.java b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/system/SwirldMain.java index 35a902c9821f..8b3b11ecd4cb 100644 --- a/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/system/SwirldMain.java +++ b/platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/system/SwirldMain.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Hedera Hashgraph, LLC + * Copyright (C) 2024-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,8 @@ package com.swirlds.platform.system; +import com.hedera.hapi.platform.event.StateSignatureTransaction; +import com.hedera.pbj.runtime.io.buffer.Bytes; import com.swirlds.common.platform.NodeId; import com.swirlds.platform.state.PlatformMerkleStateRoot; import edu.umd.cs.findbugs.annotations.NonNull; @@ -91,4 +93,14 @@ default List> getConfigDataTypes() { */ @NonNull SoftwareVersion getSoftwareVersion(); + + /** + * Encodes a system transaction to {@link Bytes} representation of a {@link com.hedera.hapi.node.base.Transaction}. + * + * @param transaction the {@link StateSignatureTransaction} to encode + * @return {@link Bytes} representation of the transaction + */ + default Bytes encodeSystemTransaction(@NonNull StateSignatureTransaction transaction) { + return Bytes.EMPTY; + } } From 77ce485132d12906e08151e94195c0e1c063606b Mon Sep 17 00:00:00 2001 From: Mustafa Uzun Date: Wed, 8 Jan 2025 17:54:14 +0200 Subject: [PATCH 02/11] test: add unit tests for the new logic in handle and prehandle Signed-off-by: Mustafa Uzun --- .../MigrationTestingTool/build.gradle.kts | 20 +- .../migration/MigrationTestingToolState.java | 2 +- .../MigrationTestingToolStateTest.java | 243 ++++++++++++++++++ 3 files changed, 263 insertions(+), 2 deletions(-) create mode 100644 platform-sdk/platform-apps/tests/MigrationTestingTool/src/test/java/com/swirlds/demo/migration/MigrationTestingToolStateTest.java diff --git a/platform-sdk/platform-apps/tests/MigrationTestingTool/build.gradle.kts b/platform-sdk/platform-apps/tests/MigrationTestingTool/build.gradle.kts index e3fca20be0ff..d414ac37b111 100644 --- a/platform-sdk/platform-apps/tests/MigrationTestingTool/build.gradle.kts +++ b/platform-sdk/platform-apps/tests/MigrationTestingTool/build.gradle.kts @@ -1,9 +1,27 @@ -// SPDX-License-Identifier: Apache-2.0 +/* + * Copyright (C) 2025 Hedera Hashgraph, LLC + * + * 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. + */ + plugins { id("org.hiero.gradle.module.application") } application.mainClass = "com.swirlds.demo.migration.MigrationTestingToolMain" testModuleInfo { + requires("com.swirlds.common.test.fixtures") requires("org.junit.jupiter.api") + requires("org.assertj.core") requires("org.junit.jupiter.params") + requires("org.mockito") } diff --git a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolState.java b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolState.java index 8c8ecfa8c76e..8f7328d12ae5 100644 --- a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolState.java +++ b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolState.java @@ -312,7 +312,7 @@ public void handleConsensusRound( if (isSystemTransaction(trans.getApplicationTransaction())) { stateSignatureTransaction.accept( new ScopedSystemTransaction(event.getCreatorId(), event.getSoftwareVersion(), event)); - return; + continue; } final MigrationTestingToolTransaction mTrans = diff --git a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/test/java/com/swirlds/demo/migration/MigrationTestingToolStateTest.java b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/test/java/com/swirlds/demo/migration/MigrationTestingToolStateTest.java new file mode 100644 index 000000000000..93890b4e4643 --- /dev/null +++ b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/test/java/com/swirlds/demo/migration/MigrationTestingToolStateTest.java @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2025 Hedera Hashgraph, LLC + * + * 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. + */ + +package com.swirlds.demo.migration; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.hedera.hapi.node.base.Timestamp; +import com.hedera.hapi.platform.event.EventCore; +import com.hedera.hapi.platform.event.EventTransaction; +import com.hedera.hapi.platform.event.EventTransaction.TransactionOneOfType; +import com.hedera.hapi.platform.event.GossipEvent; +import com.hedera.hapi.platform.event.StateSignatureTransaction; +import com.hedera.pbj.runtime.OneOf; +import com.hedera.pbj.runtime.io.buffer.Bytes; +import com.swirlds.demo.migration.MigrationTestingToolTransaction.TransactionType; +import com.swirlds.platform.components.transaction.system.ScopedSystemTransaction; +import com.swirlds.platform.event.PlatformEvent; +import com.swirlds.platform.state.PlatformStateModifier; +import com.swirlds.platform.state.StateLifecycles; +import com.swirlds.platform.system.Round; +import com.swirlds.platform.system.events.ConsensusEvent; +import com.swirlds.platform.system.transaction.ConsensusTransaction; +import com.swirlds.platform.system.transaction.Transaction; +import com.swirlds.platform.system.transaction.TransactionWrapper; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Random; +import java.util.function.Consumer; +import java.util.function.Function; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +public class MigrationTestingToolStateTest { + private static MigrationTestingToolState state; + private Random random; + private PlatformStateModifier platformStateModifier; + private Round round; + private ConsensusEvent event; + private List> consumedTransactions; + private Consumer> consumer; + private Transaction transaction; + private StateSignatureTransaction stateSignatureTransaction; + + @BeforeEach + void setUp() { + state = new MigrationTestingToolState(mock(StateLifecycles.class), mock(Function.class)); + random = new Random(); + round = mock(Round.class); + event = mock(ConsensusEvent.class); + + consumedTransactions = new ArrayList<>(); + consumer = systemTransaction -> consumedTransactions.add(systemTransaction); + transaction = mock(TransactionWrapper.class); + + final byte[] signature = new byte[384]; + random.nextBytes(signature); + final byte[] hash = new byte[48]; + random.nextBytes(hash); + stateSignatureTransaction = StateSignatureTransaction.newBuilder() + .signature(Bytes.wrap(signature)) + .hash(Bytes.wrap(hash)) + .round(round.getRoundNum()) + .build(); + } + + @Test + void handleConsensusRoundWithSystemTransaction() { + givenRoundAndEvent(); + + final var stateSignatureTransactionBytes = + StateSignatureTransaction.PROTOBUF.toBytes(stateSignatureTransaction); + when(transaction.getApplicationTransaction()).thenReturn(stateSignatureTransactionBytes); + try (MockedStatic utilities = Mockito.mockStatic(TransactionUtils.class)) { + MigrationTestingToolTransaction migrationTestingToolTransaction = + Mockito.spy(new MigrationTestingToolTransaction(TransactionType.MERKLE_MAP, 1L)); + utilities.when(() -> TransactionUtils.parseTransaction(any())).thenReturn(migrationTestingToolTransaction); + Mockito.doNothing().when(migrationTestingToolTransaction).applyTo(state); + } + state.handleConsensusRound(round, platformStateModifier, consumer); + + assertThat(consumedTransactions).hasSize(1); + } + + @Test + void handleConsensusRoundWithMultipleSystemTransactions() { + final var secondConsensusTransaction = mock(TransactionWrapper.class); + final var thirdConsensusTransaction = mock(TransactionWrapper.class); + when(round.iterator()).thenReturn(Collections.singletonList(event).iterator()); + when(event.getConsensusTimestamp()).thenReturn(Instant.now()); + when(event.consensusTransactionIterator()) + .thenReturn(List.of( + (ConsensusTransaction) transaction, + secondConsensusTransaction, + thirdConsensusTransaction) + .iterator()); + + final var stateSignatureTransactionBytes = + StateSignatureTransaction.PROTOBUF.toBytes(stateSignatureTransaction); + when(transaction.getApplicationTransaction()).thenReturn(stateSignatureTransactionBytes); + when(secondConsensusTransaction.getApplicationTransaction()).thenReturn(stateSignatureTransactionBytes); + when(thirdConsensusTransaction.getApplicationTransaction()).thenReturn(stateSignatureTransactionBytes); + + try (MockedStatic utilities = Mockito.mockStatic(TransactionUtils.class)) { + MigrationTestingToolTransaction migrationTestingToolTransaction = + Mockito.spy(new MigrationTestingToolTransaction(TransactionType.MERKLE_MAP, 1L)); + utilities.when(() -> TransactionUtils.parseTransaction(any())).thenReturn(migrationTestingToolTransaction); + Mockito.doNothing().when(migrationTestingToolTransaction).applyTo(state); + } + + state.handleConsensusRound(round, platformStateModifier, consumer); + + assertThat(consumedTransactions).hasSize(3); + } + + @Test + void handleConsensusRoundWithDeprecatedSystemTransaction() { + givenRoundAndEvent(); + + when(transaction.getApplicationTransaction()).thenReturn(Bytes.EMPTY); + when(transaction.isSystem()).thenReturn(true); + + try (MockedStatic utilities = Mockito.mockStatic(TransactionUtils.class)) { + MigrationTestingToolTransaction migrationTestingToolTransaction = + Mockito.spy(new MigrationTestingToolTransaction(TransactionType.MERKLE_MAP, 1L)); + utilities.when(() -> TransactionUtils.parseTransaction(any())).thenReturn(migrationTestingToolTransaction); + Mockito.doNothing().when(migrationTestingToolTransaction).applyTo(state); + } + + state.handleConsensusRound(round, platformStateModifier, consumer); + + assertThat(consumedTransactions).isEmpty(); + } + + @Test + void preHandleEventWithMultipleSystemTransactions() { + final var gossipEvent = mock(GossipEvent.class); + final var eventCore = mock(EventCore.class); + when(gossipEvent.eventCore()).thenReturn(eventCore); + when(eventCore.timeCreated()).thenReturn(Timestamp.DEFAULT); + when(eventCore.creatorNodeId()).thenReturn(1L); + when(eventCore.parents()).thenReturn(Collections.emptyList()); + final var eventTransaction = mock(EventTransaction.class); + final var secondEventTransaction = mock(EventTransaction.class); + final var thirdEventTransaction = mock(EventTransaction.class); + + final var stateSignatureTransactionBytes = + StateSignatureTransaction.PROTOBUF.toBytes(stateSignatureTransaction); + final var transactionProto = com.hedera.hapi.node.base.Transaction.newBuilder() + .bodyBytes(stateSignatureTransactionBytes) + .build(); + final var transactionBytes = com.hedera.hapi.node.base.Transaction.PROTOBUF.toBytes(transactionProto); + + final var systemTransactionWithType = + new OneOf<>(TransactionOneOfType.APPLICATION_TRANSACTION, transactionBytes); + + when(eventTransaction.transaction()).thenReturn(systemTransactionWithType); + when(secondEventTransaction.transaction()).thenReturn(systemTransactionWithType); + when(thirdEventTransaction.transaction()).thenReturn(systemTransactionWithType); + when(gossipEvent.eventTransaction()) + .thenReturn(List.of(eventTransaction, secondEventTransaction, thirdEventTransaction)); + event = new PlatformEvent(gossipEvent); + when(round.iterator()).thenReturn(Collections.singletonList(event).iterator()); + when(transaction.getApplicationTransaction()).thenReturn(transactionBytes); + when(secondEventTransaction.applicationTransaction()).thenReturn(transactionBytes); + when(thirdEventTransaction.applicationTransaction()).thenReturn(transactionBytes); + + state.preHandle(event, consumer); + + assertThat(consumedTransactions).hasSize(3); + } + + @Test + void preHandleEventWithSystemTransaction() { + final var gossipEvent = mock(GossipEvent.class); + final var eventCore = mock(EventCore.class); + when(eventCore.timeCreated()).thenReturn(Timestamp.DEFAULT); + when(eventCore.creatorNodeId()).thenReturn(1L); + when(eventCore.parents()).thenReturn(Collections.emptyList()); + final var eventTransaction = mock(EventTransaction.class); + when(gossipEvent.eventCore()).thenReturn(eventCore); + when(gossipEvent.eventTransaction()).thenReturn(List.of(eventTransaction)); + + final var stateSignatureTransactionBytes = + StateSignatureTransaction.PROTOBUF.toBytes(stateSignatureTransaction); + final var transactionProto = com.hedera.hapi.node.base.Transaction.newBuilder() + .bodyBytes(stateSignatureTransactionBytes) + .build(); + final var transactionBytes = com.hedera.hapi.node.base.Transaction.PROTOBUF.toBytes(transactionProto); + final var systemTransactionWithType = + new OneOf<>(TransactionOneOfType.APPLICATION_TRANSACTION, transactionBytes); + when(eventTransaction.transaction()).thenReturn(systemTransactionWithType); + + event = new PlatformEvent(gossipEvent); + + when(round.iterator()).thenReturn(Collections.singletonList(event).iterator()); + when(transaction.getApplicationTransaction()).thenReturn(transactionBytes); + + state.preHandle(event, consumer); + + assertThat(consumedTransactions).hasSize(1); + } + + @Test + void preHandleEventWithDeprecatedSystemTransaction() { + event = mock(PlatformEvent.class); + + when(round.iterator()).thenReturn(Collections.singletonList(event).iterator()); + when(transaction.isSystem()).thenReturn(true); + + state.preHandle(event, consumer); + + assertThat(consumedTransactions).isEmpty(); + } + + private void givenRoundAndEvent() { + when(round.iterator()).thenReturn(Collections.singletonList(event).iterator()); + when(event.getConsensusTimestamp()).thenReturn(Instant.now()); + when(event.consensusTransactionIterator()) + .thenReturn(Collections.singletonList((ConsensusTransaction) transaction) + .iterator()); + } +} From 2a914196bd8b49e5774ab0fd318f9fa900faacb9 Mon Sep 17 00:00:00 2001 From: Mustafa Uzun Date: Wed, 8 Jan 2025 18:04:59 +0200 Subject: [PATCH 03/11] refactor: dependency Signed-off-by: Mustafa Uzun --- .../platform-apps/tests/MigrationTestingTool/build.gradle.kts | 1 - 1 file changed, 1 deletion(-) diff --git a/platform-sdk/platform-apps/tests/MigrationTestingTool/build.gradle.kts b/platform-sdk/platform-apps/tests/MigrationTestingTool/build.gradle.kts index d414ac37b111..809f513f0913 100644 --- a/platform-sdk/platform-apps/tests/MigrationTestingTool/build.gradle.kts +++ b/platform-sdk/platform-apps/tests/MigrationTestingTool/build.gradle.kts @@ -19,7 +19,6 @@ plugins { id("org.hiero.gradle.module.application") } application.mainClass = "com.swirlds.demo.migration.MigrationTestingToolMain" testModuleInfo { - requires("com.swirlds.common.test.fixtures") requires("org.junit.jupiter.api") requires("org.assertj.core") requires("org.junit.jupiter.params") From 6caef12ec61c9e5516afba0d4689e7ead99b9b99 Mon Sep 17 00:00:00 2001 From: Mustafa Uzun Date: Thu, 9 Jan 2025 10:33:53 +0200 Subject: [PATCH 04/11] test: refactor unit tests for the new logic in handle and prehandle Signed-off-by: Mustafa Uzun --- .../MigrationTestingToolStateTest.java | 27 +------------------ 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/test/java/com/swirlds/demo/migration/MigrationTestingToolStateTest.java b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/test/java/com/swirlds/demo/migration/MigrationTestingToolStateTest.java index 93890b4e4643..de557b8b2e4b 100644 --- a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/test/java/com/swirlds/demo/migration/MigrationTestingToolStateTest.java +++ b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/test/java/com/swirlds/demo/migration/MigrationTestingToolStateTest.java @@ -17,7 +17,6 @@ package com.swirlds.demo.migration; import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -29,7 +28,6 @@ import com.hedera.hapi.platform.event.StateSignatureTransaction; import com.hedera.pbj.runtime.OneOf; import com.hedera.pbj.runtime.io.buffer.Bytes; -import com.swirlds.demo.migration.MigrationTestingToolTransaction.TransactionType; import com.swirlds.platform.components.transaction.system.ScopedSystemTransaction; import com.swirlds.platform.event.PlatformEvent; import com.swirlds.platform.state.PlatformStateModifier; @@ -48,8 +46,6 @@ import java.util.function.Function; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.mockito.MockedStatic; -import org.mockito.Mockito; public class MigrationTestingToolStateTest { private static MigrationTestingToolState state; @@ -87,16 +83,10 @@ void setUp() { @Test void handleConsensusRoundWithSystemTransaction() { givenRoundAndEvent(); - final var stateSignatureTransactionBytes = StateSignatureTransaction.PROTOBUF.toBytes(stateSignatureTransaction); when(transaction.getApplicationTransaction()).thenReturn(stateSignatureTransactionBytes); - try (MockedStatic utilities = Mockito.mockStatic(TransactionUtils.class)) { - MigrationTestingToolTransaction migrationTestingToolTransaction = - Mockito.spy(new MigrationTestingToolTransaction(TransactionType.MERKLE_MAP, 1L)); - utilities.when(() -> TransactionUtils.parseTransaction(any())).thenReturn(migrationTestingToolTransaction); - Mockito.doNothing().when(migrationTestingToolTransaction).applyTo(state); - } + state.handleConsensusRound(round, platformStateModifier, consumer); assertThat(consumedTransactions).hasSize(1); @@ -121,13 +111,6 @@ void handleConsensusRoundWithMultipleSystemTransactions() { when(secondConsensusTransaction.getApplicationTransaction()).thenReturn(stateSignatureTransactionBytes); when(thirdConsensusTransaction.getApplicationTransaction()).thenReturn(stateSignatureTransactionBytes); - try (MockedStatic utilities = Mockito.mockStatic(TransactionUtils.class)) { - MigrationTestingToolTransaction migrationTestingToolTransaction = - Mockito.spy(new MigrationTestingToolTransaction(TransactionType.MERKLE_MAP, 1L)); - utilities.when(() -> TransactionUtils.parseTransaction(any())).thenReturn(migrationTestingToolTransaction); - Mockito.doNothing().when(migrationTestingToolTransaction).applyTo(state); - } - state.handleConsensusRound(round, platformStateModifier, consumer); assertThat(consumedTransactions).hasSize(3); @@ -136,17 +119,9 @@ void handleConsensusRoundWithMultipleSystemTransactions() { @Test void handleConsensusRoundWithDeprecatedSystemTransaction() { givenRoundAndEvent(); - when(transaction.getApplicationTransaction()).thenReturn(Bytes.EMPTY); when(transaction.isSystem()).thenReturn(true); - try (MockedStatic utilities = Mockito.mockStatic(TransactionUtils.class)) { - MigrationTestingToolTransaction migrationTestingToolTransaction = - Mockito.spy(new MigrationTestingToolTransaction(TransactionType.MERKLE_MAP, 1L)); - utilities.when(() -> TransactionUtils.parseTransaction(any())).thenReturn(migrationTestingToolTransaction); - Mockito.doNothing().when(migrationTestingToolTransaction).applyTo(state); - } - state.handleConsensusRound(round, platformStateModifier, consumer); assertThat(consumedTransactions).isEmpty(); From baab5b2c2a1a5924f2cea3ba1d91f3b2abf5cfc1 Mon Sep 17 00:00:00 2001 From: Mustafa Uzun Date: Thu, 9 Jan 2025 13:34:25 +0200 Subject: [PATCH 05/11] test: add unit tests for application transaction Signed-off-by: Mustafa Uzun --- .../MigrationTestingToolStateTest.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/test/java/com/swirlds/demo/migration/MigrationTestingToolStateTest.java b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/test/java/com/swirlds/demo/migration/MigrationTestingToolStateTest.java index de557b8b2e4b..cdd0671be647 100644 --- a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/test/java/com/swirlds/demo/migration/MigrationTestingToolStateTest.java +++ b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/test/java/com/swirlds/demo/migration/MigrationTestingToolStateTest.java @@ -17,6 +17,7 @@ package com.swirlds.demo.migration; import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -37,6 +38,7 @@ import com.swirlds.platform.system.transaction.ConsensusTransaction; import com.swirlds.platform.system.transaction.Transaction; import com.swirlds.platform.system.transaction.TransactionWrapper; +import java.security.SignatureException; import java.time.Instant; import java.util.ArrayList; import java.util.Collections; @@ -46,6 +48,8 @@ import java.util.function.Function; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; public class MigrationTestingToolStateTest { private static MigrationTestingToolState state; @@ -80,6 +84,25 @@ void setUp() { .build(); } + @Test + void handleConsensusRoundWithApplicationTransaction() throws SignatureException { + givenRoundAndEvent(); + final TransactionGenerator generator = new TransactionGenerator(5); + final var bytes = Bytes.wrap(generator.generateTransaction()); + final var tr = TransactionUtils.parseTransaction(bytes); + when(transaction.getApplicationTransaction()).thenReturn(bytes); + + try (MockedStatic utilities = + Mockito.mockStatic(TransactionUtils.class, Mockito.CALLS_REAL_METHODS)) { + MigrationTestingToolTransaction migrationTestingToolTransaction = Mockito.spy(tr); + utilities.when(() -> TransactionUtils.parseTransaction(any())).thenReturn(migrationTestingToolTransaction); + Mockito.doNothing().when(migrationTestingToolTransaction).applyTo(state); + state.handleConsensusRound(round, platformStateModifier, consumer); + } + + assertThat(consumedTransactions).isEmpty(); + } + @Test void handleConsensusRoundWithSystemTransaction() { givenRoundAndEvent(); From 41a373c6c0f20cdc2ee046631dcb5b6b6d682d7d Mon Sep 17 00:00:00 2001 From: Mustafa Uzun Date: Thu, 9 Jan 2025 14:42:59 +0200 Subject: [PATCH 06/11] test: refactor unit tests Signed-off-by: Mustafa Uzun --- .../migration/MigrationTestingToolStateTest.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/test/java/com/swirlds/demo/migration/MigrationTestingToolStateTest.java b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/test/java/com/swirlds/demo/migration/MigrationTestingToolStateTest.java index cdd0671be647..42ab1c3d9b9c 100644 --- a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/test/java/com/swirlds/demo/migration/MigrationTestingToolStateTest.java +++ b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/test/java/com/swirlds/demo/migration/MigrationTestingToolStateTest.java @@ -156,8 +156,6 @@ void preHandleEventWithMultipleSystemTransactions() { final var eventCore = mock(EventCore.class); when(gossipEvent.eventCore()).thenReturn(eventCore); when(eventCore.timeCreated()).thenReturn(Timestamp.DEFAULT); - when(eventCore.creatorNodeId()).thenReturn(1L); - when(eventCore.parents()).thenReturn(Collections.emptyList()); final var eventTransaction = mock(EventTransaction.class); final var secondEventTransaction = mock(EventTransaction.class); final var thirdEventTransaction = mock(EventTransaction.class); @@ -178,10 +176,6 @@ void preHandleEventWithMultipleSystemTransactions() { when(gossipEvent.eventTransaction()) .thenReturn(List.of(eventTransaction, secondEventTransaction, thirdEventTransaction)); event = new PlatformEvent(gossipEvent); - when(round.iterator()).thenReturn(Collections.singletonList(event).iterator()); - when(transaction.getApplicationTransaction()).thenReturn(transactionBytes); - when(secondEventTransaction.applicationTransaction()).thenReturn(transactionBytes); - when(thirdEventTransaction.applicationTransaction()).thenReturn(transactionBytes); state.preHandle(event, consumer); @@ -193,8 +187,6 @@ void preHandleEventWithSystemTransaction() { final var gossipEvent = mock(GossipEvent.class); final var eventCore = mock(EventCore.class); when(eventCore.timeCreated()).thenReturn(Timestamp.DEFAULT); - when(eventCore.creatorNodeId()).thenReturn(1L); - when(eventCore.parents()).thenReturn(Collections.emptyList()); final var eventTransaction = mock(EventTransaction.class); when(gossipEvent.eventCore()).thenReturn(eventCore); when(gossipEvent.eventTransaction()).thenReturn(List.of(eventTransaction)); @@ -208,12 +200,8 @@ void preHandleEventWithSystemTransaction() { final var systemTransactionWithType = new OneOf<>(TransactionOneOfType.APPLICATION_TRANSACTION, transactionBytes); when(eventTransaction.transaction()).thenReturn(systemTransactionWithType); - event = new PlatformEvent(gossipEvent); - when(round.iterator()).thenReturn(Collections.singletonList(event).iterator()); - when(transaction.getApplicationTransaction()).thenReturn(transactionBytes); - state.preHandle(event, consumer); assertThat(consumedTransactions).hasSize(1); From 41599d581e60cb30ba4656edae9e2b633db28936 Mon Sep 17 00:00:00 2001 From: Mustafa Uzun Date: Fri, 10 Jan 2025 13:38:36 +0200 Subject: [PATCH 07/11] refactor: implementation Signed-off-by: Mustafa Uzun --- .../migration/MigrationTestingToolState.java | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolState.java b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolState.java index 8f7328d12ae5..3fda1095d649 100644 --- a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolState.java +++ b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolState.java @@ -23,6 +23,7 @@ import com.hedera.hapi.node.base.SemanticVersion; import com.hedera.hapi.platform.event.StateSignatureTransaction; +import com.hedera.pbj.runtime.ParseException; import com.swirlds.common.constructable.ConstructableIgnored; import com.swirlds.common.crypto.DigestType; import com.swirlds.common.merkle.MerkleNode; @@ -50,6 +51,7 @@ import com.swirlds.platform.system.events.ConsensusEvent; import com.swirlds.platform.system.events.Event; import com.swirlds.platform.system.transaction.ConsensusTransaction; +import com.swirlds.platform.system.transaction.Transaction; import com.swirlds.virtualmap.VirtualMap; import com.swirlds.virtualmap.datasource.VirtualDataSourceBuilder; import edu.umd.cs.findbugs.annotations.NonNull; @@ -286,8 +288,7 @@ public void preHandle( @NonNull Consumer> stateSignatureTransaction) { event.forEachTransaction(transaction -> { if (!transaction.isSystem() && isSystemTransaction(transaction.getApplicationTransaction())) { - stateSignatureTransaction.accept( - new ScopedSystemTransaction(event.getCreatorId(), event.getSoftwareVersion(), transaction)); + consumeSystemTransaction(transaction, event, stateSignatureTransaction); } }); } @@ -310,8 +311,7 @@ public void handleConsensusRound( continue; } if (isSystemTransaction(trans.getApplicationTransaction())) { - stateSignatureTransaction.accept( - new ScopedSystemTransaction(event.getCreatorId(), event.getSoftwareVersion(), event)); + consumeSystemTransaction(trans, event, stateSignatureTransaction); continue; } @@ -355,4 +355,18 @@ public int getVersion() { public int getMinimumSupportedVersion() { return ClassVersion.VIRTUAL_MAP; } + + private void consumeSystemTransaction( + final Transaction transaction, + final Event event, + final Consumer> stateSignatureTransactionCallback) { + try { + final var stateSignatureTransaction = + StateSignatureTransaction.PROTOBUF.parse(transaction.getApplicationTransaction()); + stateSignatureTransactionCallback.accept(new ScopedSystemTransaction<>( + event.getCreatorId(), event.getSoftwareVersion(), stateSignatureTransaction)); + } catch (final ParseException e) { + logger.error("Failed to parse StateSignatureTransaction", e); + } + } } From f2dc3db4c003a389f8d0a4f992fac13d7f3dab77 Mon Sep 17 00:00:00 2001 From: Mustafa Uzun Date: Fri, 10 Jan 2025 17:32:13 +0200 Subject: [PATCH 08/11] refactor: PR comments Signed-off-by: Mustafa Uzun --- .../migration/MigrationTestingToolMain.java | 3 ++- .../migration/MigrationTestingToolState.java | 23 ++++++++++++++----- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolMain.java b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolMain.java index 4ae162a76d34..cea14826eea1 100644 --- a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolMain.java +++ b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolMain.java @@ -211,7 +211,8 @@ public BasicSoftwareVersion getSoftwareVersion() { } @Override - public Bytes encodeSystemTransaction(@NonNull StateSignatureTransaction transaction) { + @NonNull + public Bytes encodeSystemTransaction(final @NonNull StateSignatureTransaction transaction) { return StateSignatureTransaction.PROTOBUF.toBytes(transaction); } } diff --git a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolState.java b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolState.java index 3fda1095d649..db801e25980a 100644 --- a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolState.java +++ b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolState.java @@ -284,10 +284,20 @@ public void init( @Override public void preHandle( - @NonNull Event event, - @NonNull Consumer> stateSignatureTransaction) { + final @NonNull Event event, + final @NonNull Consumer> stateSignatureTransaction) { event.forEachTransaction(transaction -> { - if (!transaction.isSystem() && isSystemTransaction(transaction.getApplicationTransaction())) { + + // We don't want to consume deprecated EventTransaction.STATE_SIGNATURE_TRANSACTION system transactions in + // the callback, since it's intended to be used only + // for the new form of encoded system transactions in Bytes. + // We skip the current iteration, if it processes a deprecated system transaction with the + // EventTransaction.STATE_SIGNATURE_TRANSACTION type. + if (transaction.isSystem()) { + return; + } + + if (isSystemTransaction(transaction.getApplicationTransaction())) { consumeSystemTransaction(transaction, event, stateSignatureTransaction); } }); @@ -357,9 +367,10 @@ public int getMinimumSupportedVersion() { } private void consumeSystemTransaction( - final Transaction transaction, - final Event event, - final Consumer> stateSignatureTransactionCallback) { + final @NonNull Transaction transaction, + final @NonNull Event event, + final @NonNull Consumer> + stateSignatureTransactionCallback) { try { final var stateSignatureTransaction = StateSignatureTransaction.PROTOBUF.parse(transaction.getApplicationTransaction()); From bdecb8493e90e1a009c156021ae199a2716b4826 Mon Sep 17 00:00:00 2001 From: Mustafa Uzun Date: Mon, 13 Jan 2025 12:52:03 +0200 Subject: [PATCH 09/11] refactor: PR comments Signed-off-by: Mustafa Uzun --- .../demo/migration/TransactionGenerator.java | 4 +++- .../swirlds/demo/migration/TransactionUtils.java | 16 ++++++---------- .../migration/MigrationTestingToolStateTest.java | 4 ++-- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/TransactionGenerator.java b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/TransactionGenerator.java index 9d61e9549126..f2194560614b 100644 --- a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/TransactionGenerator.java +++ b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/TransactionGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2024 Hedera Hashgraph, LLC + * Copyright (C) 2022-2025 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,6 +59,8 @@ public byte[] generateTransaction() throws SignatureException { final ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); final SerializableDataOutputStream out = new SerializableDataOutputStream(byteOut); try { + // Adding additional byte to differentiate application transactions from system ones + out.write(1); out.writeSerializable(transaction, false); } catch (final IOException e) { throw new UncheckedIOException(e); diff --git a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/TransactionUtils.java b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/TransactionUtils.java index 8459438e508c..cf4f3257a265 100644 --- a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/TransactionUtils.java +++ b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/TransactionUtils.java @@ -30,7 +30,10 @@ public class TransactionUtils { * Parse a {@link MigrationTestingToolTransaction} from a {@link Bytes}. */ public static @NonNull MigrationTestingToolTransaction parseTransaction(@NonNull final Bytes bytes) { - final SerializableDataInputStream in = new SerializableDataInputStream(bytes.toInputStream()); + // Remove the first byte, which is marker added to distinguish application transactions from system ones in + // TransactionGenerator + final Bytes slicedBytes = bytes.slice(1, bytes.length() - 1); + final SerializableDataInputStream in = new SerializableDataInputStream(slicedBytes.toInputStream()); try { return in.readSerializable(false, MigrationTestingToolTransaction::new); @@ -40,14 +43,7 @@ public class TransactionUtils { } public static boolean isSystemTransaction(@NonNull final Bytes bytes) { - final SerializableDataInputStream in = new SerializableDataInputStream(bytes.toInputStream()); - - try { - MigrationTestingToolTransaction transaction = - in.readSerializable(false, MigrationTestingToolTransaction::new); - return false; - } catch (final IOException e) { - return true; - } + byte firstByte = bytes.getByte(0); + return firstByte != 1; } } diff --git a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/test/java/com/swirlds/demo/migration/MigrationTestingToolStateTest.java b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/test/java/com/swirlds/demo/migration/MigrationTestingToolStateTest.java index 42ab1c3d9b9c..eff503460703 100644 --- a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/test/java/com/swirlds/demo/migration/MigrationTestingToolStateTest.java +++ b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/test/java/com/swirlds/demo/migration/MigrationTestingToolStateTest.java @@ -51,8 +51,8 @@ import org.mockito.MockedStatic; import org.mockito.Mockito; -public class MigrationTestingToolStateTest { - private static MigrationTestingToolState state; +class MigrationTestingToolStateTest { + private MigrationTestingToolState state; private Random random; private PlatformStateModifier platformStateModifier; private Round round; From 38facb2b0a8dfd9fe1fd5492e53eec0384c79e53 Mon Sep 17 00:00:00 2001 From: Mustafa Uzun Date: Mon, 13 Jan 2025 12:58:37 +0200 Subject: [PATCH 10/11] refactor: isSystemTransaction Signed-off-by: Mustafa Uzun --- .../main/java/com/swirlds/demo/migration/TransactionUtils.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/TransactionUtils.java b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/TransactionUtils.java index cf4f3257a265..7eb5e7e806e3 100644 --- a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/TransactionUtils.java +++ b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/TransactionUtils.java @@ -43,7 +43,6 @@ public class TransactionUtils { } public static boolean isSystemTransaction(@NonNull final Bytes bytes) { - byte firstByte = bytes.getByte(0); - return firstByte != 1; + return bytes.getByte(0) != 1; } } From 217f2dee093cf947b2485caf3400b577016a872e Mon Sep 17 00:00:00 2001 From: Mustafa Uzun Date: Mon, 13 Jan 2025 15:39:33 +0200 Subject: [PATCH 11/11] refactor: PR comment Signed-off-by: Mustafa Uzun --- .../java/com/swirlds/demo/migration/TransactionUtils.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/TransactionUtils.java b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/TransactionUtils.java index 7eb5e7e806e3..31185e89977c 100644 --- a/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/TransactionUtils.java +++ b/platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/TransactionUtils.java @@ -26,6 +26,8 @@ * Utility methods for migration testing tool transactions */ public class TransactionUtils { + private static final byte APPLICATION_TRANSACTION_MARKER = 1; + /** * Parse a {@link MigrationTestingToolTransaction} from a {@link Bytes}. */ @@ -43,6 +45,6 @@ public class TransactionUtils { } public static boolean isSystemTransaction(@NonNull final Bytes bytes) { - return bytes.getByte(0) != 1; + return bytes.getByte(0) != APPLICATION_TRANSACTION_MARKER; } }