Support code and storage for accounts in genesis config (#749)

Signed-off-by: Adrian Sutton <adrian.sutton@consensys.net>
pull/2/head
Kasper Ziemianek 6 years ago committed by Adrian Sutton
parent da651844d8
commit fcb6efe532
  1. 10
      config/src/main/java/tech/pegasys/pantheon/config/GenesisAllocation.java
  2. 52
      ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/chain/GenesisState.java
  3. 38
      ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/chain/GenesisStateTest.java
  4. 833
      ethereum/core/src/test/resources/tech/pegasys/pantheon/ethereum/chain/genesis3.json

@ -12,6 +12,8 @@
*/
package tech.pegasys.pantheon.config;
import java.util.Map;
import io.vertx.core.json.JsonObject;
public class GenesisAllocation {
@ -30,4 +32,12 @@ public class GenesisAllocation {
public String getBalance() {
return data.getString("balance", "0");
}
public String getCode() {
return data.getString("code");
}
public Map<String, Object> getStorage() {
return data.getJsonObject("storage", new JsonObject()).getMap();
}
}

@ -12,6 +12,7 @@
*/
package tech.pegasys.pantheon.ethereum.chain;
import tech.pegasys.pantheon.config.GenesisAllocation;
import tech.pegasys.pantheon.config.GenesisConfigFile;
import tech.pegasys.pantheon.ethereum.core.Address;
import tech.pegasys.pantheon.ethereum.core.Block;
@ -20,6 +21,7 @@ import tech.pegasys.pantheon.ethereum.core.BlockHeader;
import tech.pegasys.pantheon.ethereum.core.BlockHeaderBuilder;
import tech.pegasys.pantheon.ethereum.core.Hash;
import tech.pegasys.pantheon.ethereum.core.LogsBloomFilter;
import tech.pegasys.pantheon.ethereum.core.MutableAccount;
import tech.pegasys.pantheon.ethereum.core.MutableWorldState;
import tech.pegasys.pantheon.ethereum.core.Wei;
import tech.pegasys.pantheon.ethereum.core.WorldUpdater;
@ -34,8 +36,10 @@ import tech.pegasys.pantheon.util.uint.UInt256;
import java.math.BigInteger;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -75,7 +79,6 @@ public final class GenesisState {
* @param <C> The consensus context type
* @return A new {@link GenesisState}.
*/
@SuppressWarnings("unchecked")
public static <C> GenesisState fromConfig(
final GenesisConfigFile config, final ProtocolSchedule<C> protocolSchedule) {
final List<GenesisAccount> genesisAccounts =
@ -104,7 +107,12 @@ public final class GenesisState {
final MutableWorldState target, final List<GenesisAccount> genesisAccounts) {
final WorldUpdater updater = target.updater();
genesisAccounts.forEach(
account -> updater.getOrCreate(account.address).setBalance(account.balance));
genesisAccount -> {
final MutableAccount account = updater.getOrCreate(genesisAccount.address);
account.setBalance(genesisAccount.balance);
account.setCode(genesisAccount.code);
genesisAccount.storage.forEach(account::setStorageValue);
});
updater.commit();
target.persist();
}
@ -173,14 +181,8 @@ public final class GenesisState {
return Long.parseUnsignedLong(nonce, 16);
}
@SuppressWarnings("unchecked")
private static Stream<GenesisAccount> parseAllocations(final GenesisConfigFile genesis) {
return genesis
.getAllocations()
.map(
allocation ->
new GenesisAccount(
Address.fromHexString(allocation.getAddress()), allocation.getBalance()));
return genesis.getAllocations().map(GenesisAccount::fromAllocation);
}
@Override
@ -195,10 +197,26 @@ public final class GenesisState {
final Address address;
final Wei balance;
GenesisAccount(final Address address, final String balance) {
this.address = address;
final BytesValue code;
final Map<UInt256, UInt256> storage;
public static GenesisAccount fromAllocation(final GenesisAllocation allocation) {
return new GenesisAccount(
allocation.getAddress(),
allocation.getBalance(),
allocation.getCode(),
allocation.getStorage());
}
private GenesisAccount(
final String hexAddress,
final String balance,
final String hexCode,
final Map<String, Object> storage) {
this.address = Address.fromHexString(hexAddress);
this.balance = parseBalance(balance);
this.code = hexCode != null ? BytesValue.fromHexString(hexCode) : null;
this.storage = parseStorage(storage);
}
private Wei parseBalance(final String balance) {
@ -212,11 +230,21 @@ public final class GenesisState {
return Wei.of(val);
}
private Map<UInt256, UInt256> parseStorage(final Map<String, Object> storage) {
final Map<UInt256, UInt256> parsedStorage = new HashMap<>();
storage.forEach(
(key, value) ->
parsedStorage.put(UInt256.fromHexString(key), UInt256.fromHexString((String) value)));
return parsedStorage;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("address", address)
.add("balance", balance)
.add("code", code)
.add("storage", storage)
.toString();
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save