From aeb8618a4eacecc4bb030f6d3a229d5acbffdb59 Mon Sep 17 00:00:00 2001 From: Michael Tinker Date: Fri, 2 Feb 2024 16:35:35 -0600 Subject: [PATCH 1/2] Reload config from saved state Signed-off-by: Michael Tinker --- .../main/java/com/hedera/node/app/Hedera.java | 3 +- .../hedera/node/app/util/FileUtilities.java | 58 +++++++++++++++++++ .../handle/SystemFileUpdateFacility.java | 54 ++++++++--------- 3 files changed, 88 insertions(+), 27 deletions(-) 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 aea46d14f9b4..96acac5d2ac5 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 @@ -39,6 +39,7 @@ import static com.hedera.node.app.state.merkle.MerkleSchemaRegistry.isSoOrdered; import static com.hedera.node.app.throttle.ThrottleAccumulator.ThrottleType.BACKEND_THROTTLE; import static com.hedera.node.app.throttle.ThrottleAccumulator.ThrottleType.FRONTEND_THROTTLE; +import static com.hedera.node.app.util.FileUtilities.observePropertiesAndPermissions; import static com.hedera.node.app.util.HederaAsciiArt.HEDERA; import static com.swirlds.platform.system.InitTrigger.EVENT_STREAM_RECOVERY; import static com.swirlds.platform.system.InitTrigger.GENESIS; @@ -1074,6 +1075,7 @@ private void initializeForTrigger( // the various migration methods may depend on configuration to do their work logger.info("Initializing Reconnect configuration"); this.configProvider = new ConfigProviderImpl(false); + observePropertiesAndPermissions(state, configProvider.getConfiguration(), configProvider::update); logConfiguration(); logger.info("Initializing ThrottleManager"); @@ -1107,7 +1109,6 @@ private void initializeForTrigger( initializeExchangeRateManager(state); initializeFeeManager(state); initializeThrottles(state); - // TODO We may need to update the config with the latest version in file 121 } /*================================================================================================================== diff --git a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/util/FileUtilities.java b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/util/FileUtilities.java index 8d618f0af504..3fec183fa6b2 100644 --- a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/util/FileUtilities.java +++ b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/util/FileUtilities.java @@ -17,12 +17,16 @@ package com.hedera.node.app.util; import static com.hedera.node.app.service.file.impl.FileServiceImpl.BLOBS_KEY; +import static java.util.Objects.requireNonNull; import com.hedera.hapi.node.base.FileID; import com.hedera.hapi.node.state.file.File; import com.hedera.node.app.service.file.FileService; import com.hedera.node.app.state.HederaState; +import com.hedera.node.config.data.FilesConfig; +import com.hedera.node.config.data.HederaConfig; import com.hedera.pbj.runtime.io.buffer.Bytes; +import com.swirlds.config.api.Configuration; import edu.umd.cs.findbugs.annotations.NonNull; public class FileUtilities { @@ -38,4 +42,58 @@ public static Bytes getFileContent(@NonNull final HederaState state, @NonNull fi final var file = filesMap.get(fileID); return file != null ? file.contents() : Bytes.EMPTY; } + + /** + * Observes the properties and permissions of the network from a saved state. + */ + public interface SpecialFilesObserver { + /** + * Accepts the properties and permissions of the network from a saved state. + * + * @param properties the raw bytes of the properties file + * @param permissions the raw bytes of the permissions file + */ + void acceptPropertiesAndPermissions(Bytes properties, Bytes permissions); + } + + /** + * Given a state, configuration, and observer, observes the properties and + * permissions of the network. + * + * @param state the state to observe + * @param config the configuration to use + * @param observer the observer to notify + */ + public static void observePropertiesAndPermissions( + @NonNull final HederaState state, + @NonNull final Configuration config, + @NonNull final SpecialFilesObserver observer) { + requireNonNull(state); + requireNonNull(config); + requireNonNull(observer); + final var filesConfig = config.getConfigData(FilesConfig.class); + observePropertiesAndPermissions( + state, + FileUtilities.createFileID(filesConfig.networkProperties(), config), + FileUtilities.createFileID(filesConfig.hapiPermissions(), config), + observer); + } + + private static void observePropertiesAndPermissions( + @NonNull final HederaState state, + @NonNull final FileID propertiesId, + @NonNull final FileID permissionsId, + @NonNull final SpecialFilesObserver observer) { + observer.acceptPropertiesAndPermissions( + getFileContent(state, propertiesId), getFileContent(state, permissionsId)); + } + + private static FileID createFileID(final long fileNum, @NonNull final Configuration configuration) { + final var hederaConfig = configuration.getConfigData(HederaConfig.class); + return FileID.newBuilder() + .realmNum(hederaConfig.realm()) + .shardNum(hederaConfig.shard()) + .fileNum(fileNum) + .build(); + } } diff --git a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/handle/SystemFileUpdateFacility.java b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/handle/SystemFileUpdateFacility.java index 2f4f968354d2..6d708692ad9a 100644 --- a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/handle/SystemFileUpdateFacility.java +++ b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/handle/SystemFileUpdateFacility.java @@ -17,6 +17,7 @@ package com.hedera.node.app.workflows.handle; import static com.hedera.hapi.node.base.ResponseCodeEnum.SUCCESS; +import static com.hedera.node.app.util.FileUtilities.observePropertiesAndPermissions; import static java.util.Objects.requireNonNull; import static java.util.stream.Collectors.joining; @@ -33,7 +34,6 @@ import com.hedera.node.app.throttle.ThrottleManager; import com.hedera.node.app.util.FileUtilities; import com.hedera.node.config.data.FilesConfig; -import com.hedera.node.config.data.HederaConfig; import com.hedera.node.config.data.LedgerConfig; import com.hedera.pbj.runtime.ParseException; import com.hedera.pbj.runtime.io.buffer.Bytes; @@ -115,31 +115,23 @@ public ResponseCodeEnum handleTxBody(@NonNull final HederaState state, @NonNull // If it is a special file, call the updater. // We load the file only, if there is an updater for it. - final var config = configuration.getConfigData(FilesConfig.class); + final var filesConfig = configuration.getConfigData(FilesConfig.class); - if (fileNum == config.feeSchedules()) { + if (fileNum == filesConfig.feeSchedules()) { return feeManager.update(FileUtilities.getFileContent(state, fileID)); - } else if (fileNum == config.exchangeRates()) { + } else if (fileNum == filesConfig.exchangeRates()) { exchangeRateManager.update(FileUtilities.getFileContent(state, fileID), payer); - } else if (fileNum == config.networkProperties()) { - final var networkProperties = FileUtilities.getFileContent(state, fileID); - final var permissions = - FileUtilities.getFileContent(state, createFileID(config.hapiPermissions(), configuration)); - configProvider.update(networkProperties, permissions); - logContentsOf("Network properties", networkProperties); + } else if (fileNum == filesConfig.networkProperties()) { + updateConfig(configuration, ConfigType.NETWORK_PROPERTIES, state); backendThrottle.applyGasConfig(); frontendThrottle.applyGasConfig(); // Updating the multiplier source to use the new gas throttle // values that are coming from the network properties congestionMultipliers.resetExpectations(); - } else if (fileNum == config.hapiPermissions()) { - final var networkProperties = - FileUtilities.getFileContent(state, createFileID(config.networkProperties(), configuration)); - final var permissions = FileUtilities.getFileContent(state, fileID); - configProvider.update(networkProperties, permissions); - logContentsOf("API permissions", permissions); - } else if (fileNum == config.throttleDefinitions()) { + } else if (fileNum == filesConfig.hapiPermissions()) { + updateConfig(configuration, ConfigType.API_PERMISSIONS, state); + } else if (fileNum == filesConfig.throttleDefinitions()) { final var result = throttleManager.update(FileUtilities.getFileContent(state, fileID)); backendThrottle.rebuildFor(throttleManager.throttleDefinitions()); frontendThrottle.rebuildFor(throttleManager.throttleDefinitions()); @@ -151,6 +143,25 @@ public ResponseCodeEnum handleTxBody(@NonNull final HederaState state, @NonNull return SUCCESS; } + private enum ConfigType { + NETWORK_PROPERTIES, + API_PERMISSIONS, + } + + private void updateConfig( + @NonNull final Configuration configuration, + @NonNull final ConfigType configType, + @NonNull final HederaState state) { + observePropertiesAndPermissions(state, configuration, (properties, permissions) -> { + configProvider.update(properties, permissions); + if (configType == ConfigType.NETWORK_PROPERTIES) { + logContentsOf("Network properties", properties); + } else { + logContentsOf("API permissions", permissions); + } + }); + } + private void logContentsOf(@NonNull final String configFileName, @NonNull final Bytes contents) { try { final var configList = ServicesConfigurationList.PROTOBUF.parseStrict(contents.toReadableSequentialData()); @@ -165,13 +176,4 @@ private void logContentsOf(@NonNull final String configFileName, @NonNull final // If this isn't parseable we won't have updated anything, also don't log } } - - private FileID createFileID(final long fileNum, @NonNull final Configuration configuration) { - final var hederaConfig = configuration.getConfigData(HederaConfig.class); - return FileID.newBuilder() - .realmNum(hederaConfig.realm()) - .shardNum(hederaConfig.shard()) - .fileNum(fileNum) - .build(); - } } From dbbc598e4538add1f47d15fabc31187903a1d924 Mon Sep 17 00:00:00 2001 From: Michael Tinker Date: Tue, 6 Feb 2024 09:53:33 -0600 Subject: [PATCH 2/2] Wait until after onMigrate() to update config Signed-off-by: Michael Tinker --- .../hedera-app/src/main/java/com/hedera/node/app/Hedera.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 96acac5d2ac5..5f0b3c2ad40a 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 @@ -1075,8 +1075,6 @@ private void initializeForTrigger( // the various migration methods may depend on configuration to do their work logger.info("Initializing Reconnect configuration"); this.configProvider = new ConfigProviderImpl(false); - observePropertiesAndPermissions(state, configProvider.getConfiguration(), configProvider::update); - logConfiguration(); logger.info("Initializing ThrottleManager"); this.throttleManager = new ThrottleManager(); @@ -1109,6 +1107,8 @@ private void initializeForTrigger( initializeExchangeRateManager(state); initializeFeeManager(state); initializeThrottles(state); + observePropertiesAndPermissions(state, configProvider.getConfiguration(), configProvider::update); + logConfiguration(); } /*==================================================================================================================