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 76% 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..6cb83032ebd7 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 @@ -23,31 +23,25 @@ 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) { + public void restart(@NonNull final MigrationContext ctx) { + if (ctx.previousVersion() != null) { + // 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()); 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/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); 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(),