From fa319a9bd3ab2223b8ebc8875cb0a0ffcd60c386 Mon Sep 17 00:00:00 2001 From: Michael Tinker Date: Mon, 7 Oct 2024 19:06:43 -0500 Subject: [PATCH 1/3] Support restarting from RECORDS -> BOTH Signed-off-by: Michael Tinker --- .../main/java/com/hedera/node/app/Hedera.java | 4 +-- .../node/app/blocks/BlockStreamService.java | 18 ++-------- .../blocks/impl/BlockStreamManagerImpl.java | 2 +- ...chema.java => V0560BlockStreamSchema.java} | 11 +++--- .../node/app/records/BlockRecordService.java | 4 +-- ...chema.java => V0560BlockRecordSchema.java} | 32 ++++++++--------- .../app/blocks/BlockStreamServiceTest.java | 35 ++----------------- .../impl/BlockStreamManagerImplTest.java | 2 +- .../impl/BoundaryStateChangeListenerTest.java | 4 +-- ...t.java => V0560BlockStreamSchemaTest.java} | 18 +++++----- .../handle/record/BlockRecordManagerTest.java | 1 + .../handle/record/BlockRecordServiceTest.java | 4 +-- .../formats/v6/BlockRecordWriterV6Test.java | 1 - .../hedera/node/app/fixtures/AppTestBase.java | 6 ---- .../fixtures/state/FakeSchemaRegistry.java | 11 ++---- .../block/StateChangesValidator.java | 2 +- version.txt | 2 +- 17 files changed, 51 insertions(+), 106 deletions(-) rename hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/schemas/{V0540BlockStreamSchema.java => V0560BlockStreamSchema.java} (95%) rename hedera-node/hedera-app/src/main/java/com/hedera/node/app/records/schemas/{V0540BlockRecordSchema.java => V0560BlockRecordSchema.java} (57%) rename hedera-node/hedera-app/src/test/java/com/hedera/node/app/blocks/schemas/{V0540BlockStreamSchemaTest.java => V0560BlockStreamSchemaTest.java} (91%) diff --git a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/Hedera.java b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/Hedera.java index 5cf7ff07db84..a02368fadfee 100644 --- a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/Hedera.java +++ b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/Hedera.java @@ -19,7 +19,7 @@ import static com.hedera.hapi.block.stream.output.StateIdentifier.STATE_ID_BLOCK_STREAM_INFO; import static com.hedera.node.app.blocks.impl.BlockImplUtils.combine; import static com.hedera.node.app.blocks.impl.ConcurrentStreamingTreeHasher.rootHashFrom; -import static com.hedera.node.app.blocks.schemas.V0540BlockStreamSchema.BLOCK_STREAM_INFO_KEY; +import static com.hedera.node.app.blocks.schemas.V0560BlockStreamSchema.BLOCK_STREAM_INFO_KEY; import static com.hedera.node.app.info.UnavailableNetworkInfo.UNAVAILABLE_NETWORK_INFO; import static com.hedera.node.app.records.impl.BlockRecordInfoUtils.blockHashByBlockNumber; import static com.hedera.node.app.records.schemas.V0490BlockRecordSchema.BLOCK_INFO_STATE_KEY; @@ -347,7 +347,7 @@ public Hedera( new SignatureExpanderImpl(), new SignatureVerifierImpl(CryptographyHolder.get()))); contractServiceImpl = new ContractServiceImpl(appContext); - blockStreamService = new BlockStreamService(bootstrapConfig); + blockStreamService = new BlockStreamService(); // Register all service schema RuntimeConstructable factories before platform init Set.of( new EntityIdService(), diff --git a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/BlockStreamService.java b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/BlockStreamService.java index 6a08a6dbf434..98d3c1c4fcd9 100644 --- a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/BlockStreamService.java +++ b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/BlockStreamService.java @@ -16,13 +16,10 @@ package com.hedera.node.app.blocks; -import static com.hedera.node.config.types.StreamMode.RECORDS; import static java.util.Objects.requireNonNull; -import com.hedera.node.app.blocks.schemas.V0540BlockStreamSchema; -import com.hedera.node.config.data.BlockStreamConfig; +import com.hedera.node.app.blocks.schemas.V0560BlockStreamSchema; import com.hedera.pbj.runtime.io.buffer.Bytes; -import com.swirlds.config.api.Configuration; import com.swirlds.state.spi.SchemaRegistry; import com.swirlds.state.spi.Service; import edu.umd.cs.findbugs.annotations.NonNull; @@ -42,18 +39,9 @@ public class BlockStreamService implements Service { public static final String NAME = "BlockStreamService"; - private final boolean enabled; - @Nullable private Bytes migratedLastBlockHash; - /** - * Service constructor. - */ - public BlockStreamService(final Configuration config) { - this.enabled = config.getConfigData(BlockStreamConfig.class).streamMode() != RECORDS; - } - @NonNull @Override public String getServiceName() { @@ -63,9 +51,7 @@ public String getServiceName() { @Override public void registerSchemas(@NonNull final SchemaRegistry registry) { requireNonNull(registry); - if (enabled) { - registry.register(new V0540BlockStreamSchema(this::setMigratedLastBlockHash)); - } + registry.register(new V0560BlockStreamSchema(this::setMigratedLastBlockHash)); } /** diff --git a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/impl/BlockStreamManagerImpl.java b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/impl/BlockStreamManagerImpl.java index 05a3b1e78190..ca3ec1c2e58d 100644 --- a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/impl/BlockStreamManagerImpl.java +++ b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/impl/BlockStreamManagerImpl.java @@ -20,7 +20,7 @@ import static com.hedera.hapi.util.HapiUtils.asInstant; import static com.hedera.node.app.blocks.impl.BlockImplUtils.appendHash; import static com.hedera.node.app.blocks.impl.BlockImplUtils.combine; -import static com.hedera.node.app.blocks.schemas.V0540BlockStreamSchema.BLOCK_STREAM_INFO_KEY; +import static com.hedera.node.app.blocks.schemas.V0560BlockStreamSchema.BLOCK_STREAM_INFO_KEY; import static com.hedera.node.app.hapi.utils.CommonUtils.noThrowSha384HashOf; import static com.hedera.node.app.records.impl.BlockRecordInfoUtils.HASH_SIZE; import static com.swirlds.platform.state.SwirldStateManagerUtils.isInFreezePeriod; diff --git a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/schemas/V0540BlockStreamSchema.java b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/schemas/V0560BlockStreamSchema.java similarity index 95% rename from hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/schemas/V0540BlockStreamSchema.java rename to hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/schemas/V0560BlockStreamSchema.java index e4b632ff545d..877b50071069 100644 --- a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/schemas/V0540BlockStreamSchema.java +++ b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/blocks/schemas/V0560BlockStreamSchema.java @@ -54,7 +54,7 @@ *
  • The trailing 256 block hashes, used to implement the EVM {@code BLOCKHASH} opcode.
  • * */ -public class V0540BlockStreamSchema extends Schema { +public class V0560BlockStreamSchema extends Schema { public static final String BLOCK_STREAM_INFO_KEY = "BLOCK_STREAM_INFO"; private static final String SHARED_BLOCK_RECORD_INFO = "SHARED_BLOCK_RECORD_INFO"; private static final String SHARED_RUNNING_HASHES = "SHARED_RUNNING_HASHES"; @@ -63,14 +63,14 @@ public class V0540BlockStreamSchema extends Schema { * The version of the schema. */ private static final SemanticVersion VERSION = - SemanticVersion.newBuilder().major(0).minor(54).patch(0).build(); + SemanticVersion.newBuilder().major(0).minor(56).patch(0).build(); private final Consumer migratedBlockHashConsumer; /** * Schema constructor. */ - public V0540BlockStreamSchema(@NonNull final Consumer migratedBlockHashConsumer) { + public V0560BlockStreamSchema(@NonNull final Consumer migratedBlockHashConsumer) { super(VERSION); this.migratedBlockHashConsumer = requireNonNull(migratedBlockHashConsumer); } @@ -81,13 +81,14 @@ public V0540BlockStreamSchema(@NonNull final Consumer migratedBlockHashCo } @Override - public void migrate(@NonNull final MigrationContext ctx) { + public void restart(@NonNull final MigrationContext ctx) { + requireNonNull(ctx); final var state = ctx.newStates().getSingleton(BLOCK_STREAM_INFO_KEY); if (ctx.previousVersion() == null) { state.put(BlockStreamInfo.DEFAULT); } else { final var blockStreamInfo = state.get(); - // This will be null if the previous version is before 0.54.0 + // This will be null if the previous version is before 0.56.0 if (blockStreamInfo == null) { final BlockInfo blockInfo = (BlockInfo) requireNonNull(ctx.sharedValues().get(SHARED_BLOCK_RECORD_INFO)); diff --git a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/records/BlockRecordService.java b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/records/BlockRecordService.java index 97eea1909cdf..ed0b7f43c613 100644 --- a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/records/BlockRecordService.java +++ b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/records/BlockRecordService.java @@ -19,7 +19,7 @@ import com.hedera.hapi.node.base.Timestamp; import com.hedera.node.app.records.impl.BlockRecordManagerImpl; import com.hedera.node.app.records.schemas.V0490BlockRecordSchema; -import com.hedera.node.app.records.schemas.V0540BlockRecordSchema; +import com.hedera.node.app.records.schemas.V0560BlockRecordSchema; import com.swirlds.state.spi.SchemaRegistry; import com.swirlds.state.spi.Service; import edu.umd.cs.findbugs.annotations.NonNull; @@ -48,6 +48,6 @@ public String getServiceName() { @Override public void registerSchemas(@NonNull final SchemaRegistry registry) { registry.register(new V0490BlockRecordSchema()); - registry.register(new V0540BlockRecordSchema()); + registry.register(new V0560BlockRecordSchema()); } } diff --git a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/records/schemas/V0540BlockRecordSchema.java b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/records/schemas/V0560BlockRecordSchema.java similarity index 57% rename from hedera-node/hedera-app/src/main/java/com/hedera/node/app/records/schemas/V0540BlockRecordSchema.java rename to hedera-node/hedera-app/src/main/java/com/hedera/node/app/records/schemas/V0560BlockRecordSchema.java index 8460ae0036b2..ca22b2b0ed38 100644 --- a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/records/schemas/V0540BlockRecordSchema.java +++ b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/records/schemas/V0560BlockRecordSchema.java @@ -18,40 +18,40 @@ import static com.hedera.node.app.records.schemas.V0490BlockRecordSchema.BLOCK_INFO_STATE_KEY; import static com.hedera.node.app.records.schemas.V0490BlockRecordSchema.RUNNING_HASHES_STATE_KEY; +import static com.hedera.node.config.types.StreamMode.RECORDS; import com.hedera.hapi.node.base.SemanticVersion; +import com.hedera.node.config.data.BlockStreamConfig; import com.swirlds.state.spi.MigrationContext; import com.swirlds.state.spi.Schema; import edu.umd.cs.findbugs.annotations.NonNull; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -public class V0540BlockRecordSchema extends Schema { - private static final Logger logger = LogManager.getLogger(V0540BlockRecordSchema.class); +public class V0560BlockRecordSchema extends Schema { /** * The version of the schema. */ private static final SemanticVersion VERSION = - SemanticVersion.newBuilder().major(0).minor(54).patch(0).build(); + SemanticVersion.newBuilder().major(0).minor(56).patch(0).build(); private static final String SHARED_BLOCK_RECORD_INFO = "SHARED_BLOCK_RECORD_INFO"; private static final String SHARED_RUNNING_HASHES = "SHARED_RUNNING_HASHES"; - public V0540BlockRecordSchema() { + public V0560BlockRecordSchema() { super(VERSION); } - /** - * {@inheritDoc} - * */ @Override - public void migrate(@NonNull final MigrationContext ctx) { - final var isGenesis = ctx.previousVersion() == null; - if (!isGenesis) { - final var blocksState = ctx.newStates().getSingleton(BLOCK_INFO_STATE_KEY); - final var runningHashesState = ctx.newStates().getSingleton(RUNNING_HASHES_STATE_KEY); - ctx.sharedValues().put(SHARED_BLOCK_RECORD_INFO, blocksState.get()); - ctx.sharedValues().put(SHARED_RUNNING_HASHES, runningHashesState.get()); + public void restart(@NonNull final MigrationContext ctx) { + if (ctx.previousVersion() != null) { + final var streamMode = + ctx.configuration().getConfigData(BlockStreamConfig.class).streamMode(); + if (streamMode != RECORDS) { + // We need to give the upcoming BlockStreamService schemas migration info needed + final var blocksState = ctx.newStates().getSingleton(BLOCK_INFO_STATE_KEY); + final var runningHashesState = ctx.newStates().getSingleton(RUNNING_HASHES_STATE_KEY); + ctx.sharedValues().put(SHARED_BLOCK_RECORD_INFO, blocksState.get()); + ctx.sharedValues().put(SHARED_RUNNING_HASHES, runningHashesState.get()); + } } } } diff --git a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/blocks/BlockStreamServiceTest.java b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/blocks/BlockStreamServiceTest.java index d164fc526ab2..0b814a9a506b 100644 --- a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/blocks/BlockStreamServiceTest.java +++ b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/blocks/BlockStreamServiceTest.java @@ -16,14 +16,11 @@ package com.hedera.node.app.blocks; -import static com.hedera.node.app.fixtures.AppTestBase.DEFAULT_CONFIG; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoInteractions; -import com.hedera.node.app.blocks.schemas.V0540BlockStreamSchema; -import com.hedera.node.config.testfixtures.HederaTestConfigBuilder; +import com.hedera.node.app.blocks.schemas.V0560BlockStreamSchema; import com.swirlds.state.spi.SchemaRegistry; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -35,43 +32,17 @@ final class BlockStreamServiceTest { @Mock private SchemaRegistry schemaRegistry; - private BlockStreamService subject; + private final BlockStreamService subject = new BlockStreamService(); @Test void serviceNameAsExpected() { - givenDisabledSubject(); - assertThat(subject.getServiceName()).isEqualTo("BlockStreamService"); } @Test void enabledSubjectRegistersV0540Schema() { - givenEnabledSubject(); - subject.registerSchemas(schemaRegistry); - verify(schemaRegistry).register(argThat(s -> s instanceof V0540BlockStreamSchema)); - } - - @Test - void disabledSubjectDoesNotRegisterSchema() { - givenDisabledSubject(); - - subject.registerSchemas(schemaRegistry); - - verifyNoInteractions(schemaRegistry); - - assertThat(subject.migratedLastBlockHash()).isEmpty(); - } - - private void givenEnabledSubject() { - final var testConfig = HederaTestConfigBuilder.create() - .withValue("blockStream.streamMode", "BOTH") - .getOrCreateConfig(); - subject = new BlockStreamService(testConfig); - } - - private void givenDisabledSubject() { - subject = new BlockStreamService(DEFAULT_CONFIG); + verify(schemaRegistry).register(argThat(s -> s instanceof V0560BlockStreamSchema)); } } diff --git a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/blocks/impl/BlockStreamManagerImplTest.java b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/blocks/impl/BlockStreamManagerImplTest.java index 61bef3c1c404..3cb27a44f601 100644 --- a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/blocks/impl/BlockStreamManagerImplTest.java +++ b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/blocks/impl/BlockStreamManagerImplTest.java @@ -21,7 +21,7 @@ import static com.hedera.node.app.blocks.BlockStreamService.FAKE_RESTART_BLOCK_HASH; import static com.hedera.node.app.blocks.impl.BlockImplUtils.appendHash; import static com.hedera.node.app.blocks.impl.BlockImplUtils.combine; -import static com.hedera.node.app.blocks.schemas.V0540BlockStreamSchema.BLOCK_STREAM_INFO_KEY; +import static com.hedera.node.app.blocks.schemas.V0560BlockStreamSchema.BLOCK_STREAM_INFO_KEY; import static com.hedera.node.app.fixtures.AppTestBase.DEFAULT_CONFIG; import static com.hedera.node.app.hapi.utils.CommonUtils.noThrowSha384HashOf; import static com.swirlds.platform.state.service.schemas.V0540PlatformStateSchema.PLATFORM_STATE_KEY; diff --git a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/blocks/impl/BoundaryStateChangeListenerTest.java b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/blocks/impl/BoundaryStateChangeListenerTest.java index f2f52b3a93a0..77d121462675 100644 --- a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/blocks/impl/BoundaryStateChangeListenerTest.java +++ b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/blocks/impl/BoundaryStateChangeListenerTest.java @@ -31,7 +31,7 @@ import com.hedera.hapi.node.state.primitives.ProtoBytes; import com.hedera.hapi.node.state.primitives.ProtoString; import com.hedera.node.app.blocks.BlockStreamService; -import com.hedera.node.app.blocks.schemas.V0540BlockStreamSchema; +import com.hedera.node.app.blocks.schemas.V0560BlockStreamSchema; import com.hedera.pbj.runtime.io.buffer.Bytes; import java.time.Instant; import java.util.List; @@ -59,7 +59,7 @@ void targetTypesAreSingletonAndQueue() { @Test void understandsStateIds() { final var service = BlockStreamService.NAME; - final var stateKey = V0540BlockStreamSchema.BLOCK_STREAM_INFO_KEY; + final var stateKey = V0560BlockStreamSchema.BLOCK_STREAM_INFO_KEY; assertEquals(stateIdFor(service, stateKey), listener.stateIdFor(service, stateKey)); } diff --git a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/blocks/schemas/V0540BlockStreamSchemaTest.java b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/blocks/schemas/V0560BlockStreamSchemaTest.java similarity index 91% rename from hedera-node/hedera-app/src/test/java/com/hedera/node/app/blocks/schemas/V0540BlockStreamSchemaTest.java rename to hedera-node/hedera-app/src/test/java/com/hedera/node/app/blocks/schemas/V0560BlockStreamSchemaTest.java index 7e88862427b7..0b4cdfc0bb1c 100644 --- a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/blocks/schemas/V0540BlockStreamSchemaTest.java +++ b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/blocks/schemas/V0560BlockStreamSchemaTest.java @@ -16,7 +16,7 @@ package com.hedera.node.app.blocks.schemas; -import static com.hedera.node.app.blocks.schemas.V0540BlockStreamSchema.BLOCK_STREAM_INFO_KEY; +import static com.hedera.node.app.blocks.schemas.V0560BlockStreamSchema.BLOCK_STREAM_INFO_KEY; import static com.hedera.node.app.fixtures.AppTestBase.DEFAULT_CONFIG; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -43,7 +43,7 @@ import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) -public class V0540BlockStreamSchemaTest { +public class V0560BlockStreamSchemaTest { @Mock private MigrationContext migrationContext; @@ -56,16 +56,16 @@ public class V0540BlockStreamSchemaTest { @Mock private WritableSingletonState state; - private V0540BlockStreamSchema subject; + private V0560BlockStreamSchema subject; @BeforeEach void setUp() { - subject = new V0540BlockStreamSchema(migratedBlockHashConsumer); + subject = new V0560BlockStreamSchema(migratedBlockHashConsumer); } @Test - void versionIsV0540() { - assertEquals(new SemanticVersion(0, 54, 0, "", ""), subject.getVersion()); + void versionIsV0560() { + assertEquals(new SemanticVersion(0, 56, 0, "", ""), subject.getVersion()); } @Test @@ -83,7 +83,7 @@ void createsDefaultInfoAtGenesis() { given(writableStates.getSingleton(BLOCK_STREAM_INFO_KEY)) .willReturn(state); - subject.migrate(migrationContext); + subject.restart(migrationContext); verify(state).put(BlockStreamInfo.DEFAULT); } @@ -112,7 +112,7 @@ void assumesMigrationIfNotGenesisAndStateIsNull() { .willReturn(state); given(migrationContext.sharedValues()).willReturn(sharedValues); - subject.migrate(migrationContext); + subject.restart(migrationContext); verify(migratedBlockHashConsumer).accept(Bytes.fromHex("abcd".repeat(24))); final var expectedInfo = new BlockStreamInfo( @@ -136,7 +136,7 @@ void migrationIsNoopIfNotGenesisAndInfoIsNonNull() { .willReturn(state); given(state.get()).willReturn(BlockStreamInfo.DEFAULT); - subject.migrate(migrationContext); + subject.restart(migrationContext); verifyNoInteractions(migratedBlockHashConsumer); } diff --git a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/handle/record/BlockRecordManagerTest.java b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/handle/record/BlockRecordManagerTest.java index 0a3951496de0..93fada44deff 100644 --- a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/handle/record/BlockRecordManagerTest.java +++ b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/handle/record/BlockRecordManagerTest.java @@ -126,6 +126,7 @@ void setUpEach() throws Exception { .withConfigValue("hedera.recordStream.signatureFileVersion", 6) .withConfigValue("hedera.recordStream.compressFilesOnCreation", true) .withConfigValue("hedera.recordStream.sidecarMaxSizeMb", 256) + .withConfigValue("blockStream.streamMode", "BOTH") .withService(new BlockRecordService()) .withService(PLATFORM_STATE_SERVICE) .build(); diff --git a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/handle/record/BlockRecordServiceTest.java b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/handle/record/BlockRecordServiceTest.java index 1742ee7985c1..97e7bab73b84 100644 --- a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/handle/record/BlockRecordServiceTest.java +++ b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/handle/record/BlockRecordServiceTest.java @@ -30,7 +30,7 @@ import com.hedera.hapi.node.state.blockrecords.RunningHashes; import com.hedera.node.app.records.BlockRecordService; import com.hedera.node.app.records.schemas.V0490BlockRecordSchema; -import com.hedera.node.app.records.schemas.V0540BlockRecordSchema; +import com.hedera.node.app.records.schemas.V0560BlockRecordSchema; import com.hedera.pbj.runtime.io.buffer.Bytes; import com.swirlds.state.spi.MigrationContext; import com.swirlds.state.spi.Schema; @@ -89,7 +89,7 @@ void testRegisterSchemas() { runningHashesCapture.getValue()); assertEquals(new BlockInfo(-1, EPOCH, Bytes.EMPTY, EPOCH, false, EPOCH), blockInfoCapture.getValue()); } else { - assertThat(schema).isInstanceOf(V0540BlockRecordSchema.class); + assertThat(schema).isInstanceOf(V0560BlockRecordSchema.class); } return null; }); diff --git a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/handle/record/impl/producers/formats/v6/BlockRecordWriterV6Test.java b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/handle/record/impl/producers/formats/v6/BlockRecordWriterV6Test.java index 5fa0ca9f968e..11af013d79b0 100644 --- a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/handle/record/impl/producers/formats/v6/BlockRecordWriterV6Test.java +++ b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/handle/record/impl/producers/formats/v6/BlockRecordWriterV6Test.java @@ -87,7 +87,6 @@ void setUp() { appBuilder = appBuilder() .withHapiVersion(VERSION) - .withSoftwareVersion(VERSION) .withConfigValue("hedera.recordStream.enabled", true) .withConfigValue("hedera.recordStream.logDir", tempDir.toString()) .withConfigValue("hedera.recordStream.sidecarDir", "sidecar") diff --git a/hedera-node/hedera-app/src/testFixtures/java/com/hedera/node/app/fixtures/AppTestBase.java b/hedera-node/hedera-app/src/testFixtures/java/com/hedera/node/app/fixtures/AppTestBase.java index 714108232234..9d51d0e292c0 100644 --- a/hedera-node/hedera-app/src/testFixtures/java/com/hedera/node/app/fixtures/AppTestBase.java +++ b/hedera-node/hedera-app/src/testFixtures/java/com/hedera/node/app/fixtures/AppTestBase.java @@ -232,7 +232,6 @@ public void commit() { } public static final class TestAppBuilder { - private SemanticVersion softwareVersion = CURRENT_VERSION; private SemanticVersion hapiVersion = CURRENT_VERSION; private Set services = new LinkedHashSet<>(); private TestConfigBuilder configBuilder = HederaTestConfigBuilder.create(); @@ -259,11 +258,6 @@ public TestAppBuilder withHapiVersion(@NonNull final SemanticVersion version) { return this; } - public TestAppBuilder withSoftwareVersion(@NonNull final SemanticVersion version) { - this.softwareVersion = version; - return this; - } - public TestAppBuilder withConfigSource(@NonNull final ConfigSource source) { configBuilder.withSource(source); return this; diff --git a/hedera-node/hedera-app/src/testFixtures/java/com/hedera/node/app/fixtures/state/FakeSchemaRegistry.java b/hedera-node/hedera-app/src/testFixtures/java/com/hedera/node/app/fixtures/state/FakeSchemaRegistry.java index 90073caddc54..b4712d57f604 100644 --- a/hedera-node/hedera-app/src/testFixtures/java/com/hedera/node/app/fixtures/state/FakeSchemaRegistry.java +++ b/hedera-node/hedera-app/src/testFixtures/java/com/hedera/node/app/fixtures/state/FakeSchemaRegistry.java @@ -16,6 +16,7 @@ package com.hedera.node.app.fixtures.state; +import static com.hedera.node.app.fixtures.AppTestBase.DEFAULT_CONFIG; import static com.hedera.node.app.state.merkle.SchemaApplicationType.MIGRATION; import static com.hedera.node.app.state.merkle.SchemaApplicationType.RESTART; import static com.hedera.node.app.state.merkle.SchemaApplicationType.STATE_DEFINITIONS; @@ -29,7 +30,6 @@ import com.hedera.node.app.spi.state.FilteredWritableStates; import com.hedera.node.app.state.merkle.SchemaApplications; import com.swirlds.config.api.Configuration; -import com.swirlds.config.api.ConfigurationBuilder; import com.swirlds.state.spi.MigrationContext; import com.swirlds.state.spi.ReadableStates; import com.swirlds.state.spi.Schema; @@ -69,14 +69,7 @@ public SchemaRegistry register(@NonNull final Schema schema) { @SuppressWarnings("rawtypes") public void migrate( @NonNull final String serviceName, @NonNull final FakeState state, @NonNull final NetworkInfo networkInfo) { - migrate( - serviceName, - state, - CURRENT_VERSION, - networkInfo, - ConfigurationBuilder.create().build(), - new HashMap<>(), - new AtomicLong()); + migrate(serviceName, state, CURRENT_VERSION, networkInfo, DEFAULT_CONFIG, new HashMap<>(), new AtomicLong()); } public void migrate( diff --git a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/junit/support/validators/block/StateChangesValidator.java b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/junit/support/validators/block/StateChangesValidator.java index 1c3649117de4..ad59d4d5ec93 100644 --- a/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/junit/support/validators/block/StateChangesValidator.java +++ b/hedera-node/test-clients/src/main/java/com/hedera/services/bdd/junit/support/validators/block/StateChangesValidator.java @@ -529,7 +529,7 @@ private void registerServices( new UtilServiceImpl(), new RecordCacheService(), new BlockRecordService(), - new BlockStreamService(bootstrapConfig), + new BlockStreamService(), new FeeService(), new CongestionThrottleService(), new NetworkServiceImpl(), diff --git a/version.txt b/version.txt index 2f4c74eb2dda..25a153f0a959 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.56.0 +0.56.1 From 899f8cf158764aaa49af1b2e877533578bb1bc60 Mon Sep 17 00:00:00 2001 From: Michael Tinker Date: Mon, 7 Oct 2024 19:09:29 -0500 Subject: [PATCH 2/3] Revert version.txt change Signed-off-by: Michael Tinker --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index 25a153f0a959..2f4c74eb2dda 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.56.1 +0.56.0 From 4f9d92df5a7faee80bfd5d2121c0956d29def8d4 Mon Sep 17 00:00:00 2001 From: Michael Tinker Date: Tue, 8 Oct 2024 09:09:53 -0500 Subject: [PATCH 3/3] Always give BlockStreamSchema migration info for now Signed-off-by: Michael Tinker --- .../schemas/V0560BlockRecordSchema.java | 16 +++----- .../node/config/data/StakingConfig.java | 2 + .../staking/StakingRewardsHelper.java | 39 +++++++++++++------ .../EndOfStakingPeriodUpdaterTest.java | 3 +- .../handlers/staking/StakeInfoHelperTest.java | 2 +- .../StakingRewardsHandlerImplTest.java | 2 +- .../staking/StakingRewardsHelperTest.java | 21 +++++++--- 7 files changed, 53 insertions(+), 32 deletions(-) diff --git a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/records/schemas/V0560BlockRecordSchema.java b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/records/schemas/V0560BlockRecordSchema.java index ca22b2b0ed38..6cb83032ebd7 100644 --- a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/records/schemas/V0560BlockRecordSchema.java +++ b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/records/schemas/V0560BlockRecordSchema.java @@ -18,10 +18,8 @@ import static com.hedera.node.app.records.schemas.V0490BlockRecordSchema.BLOCK_INFO_STATE_KEY; import static com.hedera.node.app.records.schemas.V0490BlockRecordSchema.RUNNING_HASHES_STATE_KEY; -import static com.hedera.node.config.types.StreamMode.RECORDS; import com.hedera.hapi.node.base.SemanticVersion; -import com.hedera.node.config.data.BlockStreamConfig; import com.swirlds.state.spi.MigrationContext; import com.swirlds.state.spi.Schema; import edu.umd.cs.findbugs.annotations.NonNull; @@ -43,15 +41,11 @@ public V0560BlockRecordSchema() { @Override public void restart(@NonNull final MigrationContext ctx) { if (ctx.previousVersion() != null) { - final var streamMode = - ctx.configuration().getConfigData(BlockStreamConfig.class).streamMode(); - if (streamMode != RECORDS) { - // We need to give the upcoming BlockStreamService schemas migration info needed - final var blocksState = ctx.newStates().getSingleton(BLOCK_INFO_STATE_KEY); - final var runningHashesState = ctx.newStates().getSingleton(RUNNING_HASHES_STATE_KEY); - ctx.sharedValues().put(SHARED_BLOCK_RECORD_INFO, blocksState.get()); - ctx.sharedValues().put(SHARED_RUNNING_HASHES, runningHashesState.get()); - } + // Upcoming BlockStreamService schemas may need migration info + final var blocksState = ctx.newStates().getSingleton(BLOCK_INFO_STATE_KEY); + final var runningHashesState = ctx.newStates().getSingleton(RUNNING_HASHES_STATE_KEY); + ctx.sharedValues().put(SHARED_BLOCK_RECORD_INFO, blocksState.get()); + ctx.sharedValues().put(SHARED_RUNNING_HASHES, runningHashesState.get()); } } } diff --git a/hedera-node/hedera-config/src/main/java/com/hedera/node/config/data/StakingConfig.java b/hedera-node/hedera-config/src/main/java/com/hedera/node/config/data/StakingConfig.java index c885e2fecffd..b2b907d988cf 100644 --- a/hedera-node/hedera-config/src/main/java/com/hedera/node/config/data/StakingConfig.java +++ b/hedera-node/hedera-config/src/main/java/com/hedera/node/config/data/StakingConfig.java @@ -34,6 +34,8 @@ public record StakingConfig( // @ConfigProperty(defaultValue = "") Map nodeMaxToMinStakeRatios, @ConfigProperty(defaultValue = "true") @NetworkProperty boolean isEnabled, @ConfigProperty(defaultValue = "false") @NetworkProperty boolean requireMinStakeToReward, + // Assume there should have been no skipped staking periods + @ConfigProperty(defaultValue = "true") @NetworkProperty boolean assumeContiguousPeriods, // Can be renamed to just "rewardRate" when the "staking.rewardRate" property is removed // from all production 0.0.121 system files @ConfigProperty(defaultValue = "6849") @NetworkProperty long perHbarRewardRate, diff --git a/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/staking/StakingRewardsHelper.java b/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/staking/StakingRewardsHelper.java index 2aacdc67b720..70604e77649f 100644 --- a/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/staking/StakingRewardsHelper.java +++ b/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/staking/StakingRewardsHelper.java @@ -29,6 +29,8 @@ import com.hedera.node.app.service.token.impl.WritableAccountStore; import com.hedera.node.app.service.token.impl.WritableNetworkStakingRewardsStore; import com.hedera.node.app.service.token.impl.WritableStakingInfoStore; +import com.hedera.node.config.ConfigProvider; +import com.hedera.node.config.data.StakingConfig; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.util.ArrayList; @@ -53,12 +55,18 @@ public class StakingRewardsHelper { */ public static final long MAX_PENDING_REWARDS = 50_000_000_000L * HBARS_TO_TINYBARS; + private final boolean assumeContiguousPeriods; + /** * Default constructor for injection. */ @Inject - public StakingRewardsHelper() { - // Exists for Dagger injection + public StakingRewardsHelper(@NonNull final ConfigProvider configProvider) { + requireNonNull(configProvider); + this.assumeContiguousPeriods = configProvider + .getConfiguration() + .getConfigData(StakingConfig.class) + .assumeContiguousPeriods(); } /** @@ -171,11 +179,14 @@ public void decreasePendingRewardsBy( final var currentPendingRewards = stakingRewardsStore.pendingRewards(); var newPendingRewards = currentPendingRewards - amount; if (newPendingRewards < 0) { - log.error( - "Pending rewards decreased by {} to a meaningless {}, fixing to zero hbar", - amount, - newPendingRewards, - nodeId); + // If staking periods have been skipped in an environment, it is no longer + // guaranteed that pending rewards are maintained accurately + if (assumeContiguousPeriods) { + log.error( + "Pending rewards decreased by {} to a meaningless {}, fixing to zero hbar", + amount, + newPendingRewards); + } newPendingRewards = 0; } final var stakingRewards = stakingRewardsStore.get(); @@ -187,11 +198,15 @@ public void decreasePendingRewardsBy( final var currentNodePendingRewards = stakingInfo.pendingRewards(); var newNodePendingRewards = currentNodePendingRewards - amount; if (newNodePendingRewards < 0) { - log.error( - "Pending rewards decreased by {} to a meaningless {} for node {}, fixing to zero hbar", - amount, - newNodePendingRewards, - nodeId); + // If staking periods have been skipped in an environment, it is no longer + // guaranteed that pending rewards are maintained accurately + if (assumeContiguousPeriods) { + log.error( + "Pending rewards decreased by {} to a meaningless {} for node {}, fixing to zero hbar", + amount, + newNodePendingRewards, + nodeId); + } newNodePendingRewards = 0; } final var stakingInfoCopy = diff --git a/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/staking/EndOfStakingPeriodUpdaterTest.java b/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/staking/EndOfStakingPeriodUpdaterTest.java index bfa41d3d2f4b..d5bbfdeb8e50 100644 --- a/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/staking/EndOfStakingPeriodUpdaterTest.java +++ b/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/staking/EndOfStakingPeriodUpdaterTest.java @@ -99,7 +99,8 @@ void setup() { .accountId(asAccount(800)) .tinybarBalance(100_000_000_000L) .build()); - subject = new EndOfStakingPeriodUpdater(new StakingRewardsHelper(), DEFAULT_CONFIG_PROVIDER); + subject = new EndOfStakingPeriodUpdater( + new StakingRewardsHelper(DEFAULT_CONFIG_PROVIDER), DEFAULT_CONFIG_PROVIDER); } @Test diff --git a/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/staking/StakeInfoHelperTest.java b/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/staking/StakeInfoHelperTest.java index aa2fa8a03e63..fd0d2c2cc7b4 100644 --- a/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/staking/StakeInfoHelperTest.java +++ b/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/staking/StakeInfoHelperTest.java @@ -57,7 +57,7 @@ @ExtendWith(MockitoExtension.class) class StakeInfoHelperTest { - private static final Configuration DEFAULT_CONFIG = HederaTestConfigBuilder.createConfig(); + public static final Configuration DEFAULT_CONFIG = HederaTestConfigBuilder.createConfig(); private WritableStakingInfoStore infoStore; diff --git a/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/staking/StakingRewardsHandlerImplTest.java b/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/staking/StakingRewardsHandlerImplTest.java index 24d1ff39c8fe..20a5c0c5edf8 100644 --- a/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/staking/StakingRewardsHandlerImplTest.java +++ b/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/staking/StakingRewardsHandlerImplTest.java @@ -91,7 +91,7 @@ public void setUp() { given(context.consensusTime()).willReturn(consensusInstant); givenStoresAndConfig(context); - stakingRewardHelper = new StakingRewardsHelper(); + stakingRewardHelper = new StakingRewardsHelper(configProvider); stakePeriodManager = new StakePeriodManager(configProvider, instantSource); stakeRewardCalculator = new StakeRewardCalculatorImpl(stakePeriodManager); rewardsPayer = new StakingRewardsDistributor(stakingRewardHelper, stakeRewardCalculator); diff --git a/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/staking/StakingRewardsHelperTest.java b/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/staking/StakingRewardsHelperTest.java index 96d6a26e3af1..82986bc136e8 100644 --- a/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/staking/StakingRewardsHelperTest.java +++ b/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/staking/StakingRewardsHelperTest.java @@ -18,7 +18,9 @@ import static com.hedera.node.app.service.token.impl.handlers.staking.StakingRewardsHelper.MAX_PENDING_REWARDS; import static com.hedera.node.app.service.token.impl.handlers.staking.StakingRewardsHelper.requiresExternalization; +import static com.hedera.node.app.service.token.impl.test.handlers.staking.StakeInfoHelperTest.DEFAULT_CONFIG; import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; +import static org.mockito.BDDMockito.given; import com.hedera.hapi.node.base.AccountAmount; import com.hedera.hapi.node.base.AccountID; @@ -28,24 +30,34 @@ import com.hedera.node.app.spi.fixtures.util.LogCaptureExtension; import com.hedera.node.app.spi.fixtures.util.LoggingSubject; import com.hedera.node.app.spi.fixtures.util.LoggingTarget; +import com.hedera.node.config.ConfigProvider; +import com.hedera.node.config.VersionedConfigImpl; import java.util.Map; import java.util.Set; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; -@ExtendWith(LogCaptureExtension.class) +@ExtendWith({MockitoExtension.class, LogCaptureExtension.class}) class StakingRewardsHelperTest extends CryptoTokenHandlerTestBase { - @LoggingSubject - private StakingRewardsHelper subject = new StakingRewardsHelper(); @LoggingTarget private LogCaptor logCaptor; + @Mock + private ConfigProvider configProvider; + + @LoggingSubject + private StakingRewardsHelper subject; + @BeforeEach public void setUp() { super.setUp(); refreshWritableStores(); + given(configProvider.getConfiguration()).willReturn(new VersionedConfigImpl(DEFAULT_CONFIG, 1)); + subject = new StakingRewardsHelper(configProvider); } @Test @@ -175,7 +187,6 @@ void decreasesPendingRewardsToZeroInStakingInfoMapIfNegative() { @Test void increasesPendingRewardsAccurately() { - final var subject = new StakingRewardsHelper(); assertThat(writableRewardsStore.get().pendingRewards()).isEqualTo(1000L); final var copyStakingInfo = subject.increasePendingRewardsBy(writableRewardsStore, 100L, writableStakingInfoStore.get(0L)); @@ -184,7 +195,6 @@ void increasesPendingRewardsAccurately() { @Test void increasesPendingRewardsByZeroIfStkingInfoShowsDeleted() { - final var subject = new StakingRewardsHelper(); writableStakingInfoStore.put( node0Id.number(), node0Info.copyBuilder().deleted(true).build()); assertThat(writableStakingInfoStore.get(0).pendingRewards()).isEqualTo(1000000L); @@ -197,7 +207,6 @@ void increasesPendingRewardsByZeroIfStkingInfoShowsDeleted() { @Test void increasesPendingRewardsByMaxValueIfVeryLargeNumber() { - final var subject = new StakingRewardsHelper(); assertThat(writableStakingInfoStore.get(0).pendingRewards()).isEqualTo(1000000L); assertThat(writableRewardsStore.get().pendingRewards()).isEqualTo(1000L);