-
Notifications
You must be signed in to change notification settings - Fork 837
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add Ephemery genesis config file Signed-off-by: gconnect <[email protected]> --------- Signed-off-by: gconnect <[email protected]> Signed-off-by: Glory Agatevure <[email protected]> Co-authored-by: Sally MacFarlane <[email protected]>
- Loading branch information
Showing
10 changed files
with
1,180 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
81 changes: 81 additions & 0 deletions
81
besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisUpdater.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/* | ||
* Copyright contributors to Hyperledger Besu. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on | ||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations under the License. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
package org.hyperledger.besu.util; | ||
|
||
import static org.hyperledger.besu.cli.config.NetworkName.EPHEMERY; | ||
|
||
import org.hyperledger.besu.config.GenesisConfigFile; | ||
|
||
import java.io.IOException; | ||
import java.math.BigInteger; | ||
import java.time.Instant; | ||
import java.time.temporal.ChronoUnit; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
|
||
/** | ||
* The Generate Ephemery Genesis Updater. Checks for update based on the set period and update the | ||
* Ephemery genesis in memory | ||
*/ | ||
public class EphemeryGenesisUpdater { | ||
private static final int PERIOD_IN_DAYS = 28; | ||
private static final long PERIOD_IN_SECONDS = (PERIOD_IN_DAYS * 24 * 60 * 60); | ||
|
||
/** | ||
* Constructor for EphemeryGenesisUpdater. Initializes the genesis updater for the Ephemery | ||
* network. | ||
*/ | ||
public EphemeryGenesisUpdater() {} | ||
|
||
/** | ||
* Updates the Ephemery genesis configuration based on the predefined period. | ||
* | ||
* @param overrides a map of configuration overrides | ||
* @return the updated GenesisConfigFile | ||
* @throws RuntimeException if an error occurs during the update process | ||
*/ | ||
public static GenesisConfigFile updateGenesis(final Map<String, String> overrides) | ||
throws RuntimeException { | ||
GenesisConfigFile genesisConfigFile; | ||
try { | ||
if (EPHEMERY.getGenesisFile() == null) { | ||
throw new IOException("Genesis file or config options are null"); | ||
} | ||
genesisConfigFile = GenesisConfigFile.fromResource(EPHEMERY.getGenesisFile()); | ||
long genesisTimestamp = genesisConfigFile.getTimestamp(); | ||
Optional<BigInteger> genesisChainId = genesisConfigFile.getConfigOptions().getChainId(); | ||
long currentTimestamp = Instant.now().getEpochSecond(); | ||
long periodsSinceGenesis = | ||
ChronoUnit.DAYS.between(Instant.ofEpochSecond(genesisTimestamp), Instant.now()) | ||
/ PERIOD_IN_DAYS; | ||
|
||
long updatedTimestamp = genesisTimestamp + (periodsSinceGenesis * PERIOD_IN_SECONDS); | ||
BigInteger updatedChainId = | ||
genesisChainId | ||
.orElseThrow(() -> new IllegalStateException("ChainId not present")) | ||
.add(BigInteger.valueOf(periodsSinceGenesis)); | ||
// has a period elapsed since original ephemery genesis time? if so, override chainId and | ||
// timestamp | ||
if (currentTimestamp > (genesisTimestamp + PERIOD_IN_SECONDS)) { | ||
overrides.put("chainId", String.valueOf(updatedChainId)); | ||
overrides.put("timestamp", String.valueOf(updatedTimestamp)); | ||
genesisConfigFile = genesisConfigFile.withOverrides(overrides); | ||
} | ||
return genesisConfigFile.withOverrides(overrides); | ||
} catch (IOException e) { | ||
throw new RuntimeException("Error updating ephemery genesis: " + e.getMessage(), e); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
139 changes: 139 additions & 0 deletions
139
besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisUpdaterTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
/* | ||
* Copyright contributors to Hyperledger Besu. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on | ||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations under the License. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
package org.hyperledger.besu.util; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||
import static org.hyperledger.besu.config.GenesisConfigFile.fromConfig; | ||
|
||
import org.hyperledger.besu.config.GenesisConfigFile; | ||
|
||
import java.math.BigInteger; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
import java.util.TreeMap; | ||
|
||
import io.vertx.core.json.JsonObject; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.ExtendWith; | ||
import org.mockito.junit.jupiter.MockitoExtension; | ||
|
||
@ExtendWith(MockitoExtension.class) | ||
public class EphemeryGenesisUpdaterTest { | ||
private static final int GENESIS_CONFIG_TEST_CHAINID = 39438135; | ||
private static final long GENESIS_TEST_TIMESTAMP = 1720119600; | ||
private static final long EARLIER_TIMESTAMP = 1712041200; | ||
private static final long LATER_TIMESTAMP = 1922041200; | ||
private static final long PERIOD_IN_SECONDS = 28 * 24 * 60 * 60; | ||
private static final long PERIOD_SINCE_GENESIS = 3; | ||
|
||
private static final JsonObject VALID_GENESIS_JSON = | ||
(new JsonObject()) | ||
.put("config", (new JsonObject()).put("chainId", GENESIS_CONFIG_TEST_CHAINID)) | ||
.put("timestamp", GENESIS_TEST_TIMESTAMP); | ||
|
||
private static final GenesisConfigFile INVALID_GENESIS_JSON = fromConfig("{}"); | ||
private static final JsonObject INVALID_GENESIS_JSON_WITHOUT_CHAINID = | ||
(new JsonObject()).put("timestamp", GENESIS_TEST_TIMESTAMP); | ||
|
||
private static final JsonObject INVALID_GENESIS_JSON_WITHOUT_TIMESTAMP = | ||
new JsonObject() | ||
.put("config", (new JsonObject()).put("chainId", GENESIS_CONFIG_TEST_CHAINID)); | ||
|
||
@Test | ||
public void testEphemeryWhenChainIdIsAbsent() { | ||
final GenesisConfigFile config = | ||
GenesisConfigFile.fromConfig(INVALID_GENESIS_JSON_WITHOUT_CHAINID.toString()); | ||
Optional<BigInteger> chainId = config.getConfigOptions().getChainId(); | ||
assertThat(chainId).isNotPresent(); | ||
} | ||
|
||
@Test | ||
public void testShouldDefaultTimestampToZero() { | ||
final GenesisConfigFile config = | ||
GenesisConfigFile.fromConfig(INVALID_GENESIS_JSON_WITHOUT_TIMESTAMP.toString()); | ||
assertThat(config.getTimestamp()).isZero(); | ||
} | ||
|
||
@Test | ||
public void testEphemeryWhenGenesisJsonIsInvalid() { | ||
assertThatThrownBy(INVALID_GENESIS_JSON::getDifficulty) | ||
.isInstanceOf(IllegalArgumentException.class) | ||
.hasMessageContaining("Invalid genesis block configuration"); | ||
} | ||
|
||
@Test | ||
public void testEphemeryWhenGenesisJsonIsValid() { | ||
final GenesisConfigFile config = GenesisConfigFile.fromConfig(VALID_GENESIS_JSON.toString()); | ||
assertThat(String.valueOf(config.getTimestamp())) | ||
.isEqualTo(String.valueOf(GENESIS_TEST_TIMESTAMP)); | ||
assertThat(config.getConfigOptions().getChainId()) | ||
.hasValue(BigInteger.valueOf(GENESIS_CONFIG_TEST_CHAINID)); | ||
assertThat(String.valueOf(config.getTimestamp())).isNotNull(); | ||
assertThat(String.valueOf(config.getTimestamp())).isNotEmpty(); | ||
} | ||
|
||
@Test | ||
public void testEphemeryNotYetDueForUpdate() { | ||
final GenesisConfigFile config = GenesisConfigFile.fromConfig(VALID_GENESIS_JSON.toString()); | ||
assertThat(EARLIER_TIMESTAMP).isLessThan(config.getTimestamp() + PERIOD_IN_SECONDS); | ||
} | ||
|
||
@Test | ||
void testOverrideWithUpdatedChainIdAndTimeStamp() { | ||
BigInteger expectedChainId = | ||
BigInteger.valueOf(GENESIS_CONFIG_TEST_CHAINID) | ||
.add(BigInteger.valueOf(PERIOD_SINCE_GENESIS)); | ||
|
||
long expectedGenesisTimestamp = | ||
GENESIS_TEST_TIMESTAMP + (PERIOD_SINCE_GENESIS * PERIOD_IN_SECONDS); | ||
|
||
final GenesisConfigFile config = GenesisConfigFile.fromResource("/ephemery.json"); | ||
|
||
final Map<String, String> override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); | ||
override.put("chainId", String.valueOf(expectedChainId)); | ||
override.put("timestamp", String.valueOf(expectedGenesisTimestamp)); | ||
|
||
assertThat(config.withOverrides(override).getConfigOptions().getChainId()).isPresent(); | ||
assertThat(config.withOverrides(override).getConfigOptions().getChainId()) | ||
.hasValue(expectedChainId); | ||
assertThat(config.withOverrides(override).getTimestamp()).isNotNull(); | ||
assertThat(expectedChainId).isEqualTo(override.get("chainId")); | ||
assertThat(String.valueOf(expectedGenesisTimestamp)).isEqualTo(override.get("timestamp")); | ||
} | ||
|
||
@Test | ||
public void testEphemeryWhenSuccessful() { | ||
final GenesisConfigFile config = GenesisConfigFile.fromConfig(VALID_GENESIS_JSON.toString()); | ||
|
||
BigInteger expectedChainId = | ||
BigInteger.valueOf(GENESIS_CONFIG_TEST_CHAINID) | ||
.add(BigInteger.valueOf(PERIOD_SINCE_GENESIS)); | ||
|
||
long expectedGenesisTimestamp = | ||
GENESIS_TEST_TIMESTAMP + (PERIOD_SINCE_GENESIS * PERIOD_IN_SECONDS); | ||
final Map<String, String> override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); | ||
override.put("chainId", String.valueOf(expectedChainId)); | ||
override.put("timestamp", String.valueOf(expectedGenesisTimestamp)); | ||
final GenesisConfigFile updatedConfig = config.withOverrides(override); | ||
|
||
assertThat(LATER_TIMESTAMP) | ||
.isGreaterThan(Long.parseLong(String.valueOf(GENESIS_TEST_TIMESTAMP + PERIOD_IN_SECONDS))); | ||
assertThat(updatedConfig.getConfigOptions().getChainId()).hasValue(expectedChainId); | ||
assertThat(updatedConfig.getTimestamp()).isEqualTo(expectedGenesisTimestamp); | ||
assertThat(override.get("timestamp")).isEqualTo(String.valueOf(expectedGenesisTimestamp)); | ||
assertThat(override.get("chainId")).isEqualTo(expectedChainId.toString()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.