Skip to content
This repository has been archived by the owner on Sep 26, 2019. It is now read-only.

Commit

Permalink
[PAN-2829] Add opcode and precompiled support for versioning
Browse files Browse the repository at this point in the history
Different precompile sets for different account versions
  • Loading branch information
shemnon committed Jul 12, 2019
1 parent 1b792fb commit ee224b1
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ public void start(final MessageFrame frame) {
transferValue(frame);

// Check first if the message call is to a pre-compile contract
final PrecompiledContract precompile = precompiles.get(frame.getContractAddress());
final PrecompiledContract precompile =
precompiles.get(frame.getContractAddress(), frame.getContractAccountVersion());
if (precompile != null) {
executePrecompile(precompile, frame);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
package tech.pegasys.pantheon.ethereum.mainnet;

import tech.pegasys.pantheon.ethereum.core.Account;
import tech.pegasys.pantheon.ethereum.core.Address;
import tech.pegasys.pantheon.ethereum.mainnet.precompiles.AltBN128AddPrecompiledContract;
import tech.pegasys.pantheon.ethereum.mainnet.precompiles.AltBN128MulPrecompiledContract;
Expand All @@ -30,45 +31,70 @@ public abstract class MainnetPrecompiledContractRegistries {
private MainnetPrecompiledContractRegistries() {}

private static void populateForFrontier(
final PrecompileContractRegistry registry, final GasCalculator gasCalculator) {
registry.put(Address.ECREC, new ECRECPrecompiledContract(gasCalculator));
registry.put(Address.SHA256, new SHA256PrecompiledContract(gasCalculator));
registry.put(Address.RIPEMD160, new RIPEMD160PrecompiledContract(gasCalculator));
registry.put(Address.ID, new IDPrecompiledContract(gasCalculator));
final PrecompileContractRegistry registry,
final GasCalculator gasCalculator,
final int accountVersion) {
registry.put(Address.ECREC, accountVersion, new ECRECPrecompiledContract(gasCalculator));
registry.put(Address.SHA256, accountVersion, new SHA256PrecompiledContract(gasCalculator));
registry.put(
Address.RIPEMD160, accountVersion, new RIPEMD160PrecompiledContract(gasCalculator));
registry.put(Address.ID, accountVersion, new IDPrecompiledContract(gasCalculator));
}

public static PrecompileContractRegistry frontier(
final PrecompiledContractConfiguration precompiledContractConfiguration) {
final PrecompileContractRegistry registry = new PrecompileContractRegistry();
populateForFrontier(registry, precompiledContractConfiguration.getGasCalculator());
populateForFrontier(
registry, precompiledContractConfiguration.getGasCalculator(), Account.DEFAULT_VERSION);
return registry;
}

private static void populateForByzantium(
final PrecompileContractRegistry registry, final GasCalculator gasCalculator) {
populateForFrontier(registry, gasCalculator);
final PrecompileContractRegistry registry,
final GasCalculator gasCalculator,
final int accountVersion) {
populateForFrontier(registry, gasCalculator, accountVersion);
registry.put(
Address.MODEXP,
accountVersion,
new BigIntegerModularExponentiationPrecompiledContract(gasCalculator));
registry.put(
Address.ALTBN128_ADD, accountVersion, new AltBN128AddPrecompiledContract(gasCalculator));
registry.put(
Address.ALTBN128_MUL, accountVersion, new AltBN128MulPrecompiledContract(gasCalculator));
registry.put(
Address.MODEXP, new BigIntegerModularExponentiationPrecompiledContract(gasCalculator));
registry.put(Address.ALTBN128_ADD, new AltBN128AddPrecompiledContract(gasCalculator));
registry.put(Address.ALTBN128_MUL, new AltBN128MulPrecompiledContract(gasCalculator));
registry.put(Address.ALTBN128_PAIRING, new AltBN128PairingPrecompiledContract(gasCalculator));
Address.ALTBN128_PAIRING,
accountVersion,
new AltBN128PairingPrecompiledContract(gasCalculator));
}

public static PrecompileContractRegistry byzantium(
final PrecompiledContractConfiguration precompiledContractConfiguration) {
final PrecompileContractRegistry registry = new PrecompileContractRegistry();
populateForByzantium(registry, precompiledContractConfiguration.getGasCalculator());
populateForByzantium(
registry, precompiledContractConfiguration.getGasCalculator(), Account.DEFAULT_VERSION);
return registry;
}

public static PrecompileContractRegistry appendPrivacy(
final PrecompileContractRegistry registry,
public static PrecompileContractRegistry istanbul(
final PrecompiledContractConfiguration precompiledContractConfiguration) {
Address address =
final PrecompileContractRegistry registry = new PrecompileContractRegistry();
populateForByzantium(
registry, precompiledContractConfiguration.getGasCalculator(), Account.DEFAULT_VERSION);
populateForByzantium(registry, precompiledContractConfiguration.getGasCalculator(), 1);
return registry;
}

static PrecompileContractRegistry appendPrivacy(
final PrecompileContractRegistry registry,
final PrecompiledContractConfiguration precompiledContractConfiguration,
final int accountVersion) {
final Address address =
Address.privacyPrecompiled(
precompiledContractConfiguration.getPrivacyParameters().getPrivacyAddress());
registry.put(
address,
accountVersion,
new PrivacyPrecompiledContract(
precompiledContractConfiguration.getGasCalculator(),
precompiledContractConfiguration.getPrivacyParameters()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,26 @@

import tech.pegasys.pantheon.ethereum.core.Address;

import java.util.HashMap;
import java.util.Map;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;

/** Encapsulates a group of {@link PrecompiledContract}s used together. */
public class PrecompileContractRegistry {

private final Map<Address, PrecompiledContract> precompiles;
private final Table<Address, Integer, PrecompiledContract> precompiles;

public PrecompileContractRegistry() {
this.precompiles = new HashMap<>();
this.precompiles = HashBasedTable.create(16, 2);
}

public PrecompiledContract get(final Address address) {
return precompiles.get(address);
public PrecompiledContract get(final Address address, final int contractAccountVersion) {
return precompiles.get(address, contractAccountVersion);
}

public void put(final Address address, final PrecompiledContract precompile) {
precompiles.put(address, precompile);
public void put(
final Address address,
final int contractAccountVersion,
final PrecompiledContract precompile) {
precompiles.put(address, contractAccountVersion, precompile);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import static com.google.common.base.Preconditions.checkNotNull;

import tech.pegasys.pantheon.ethereum.BlockValidator;
import tech.pegasys.pantheon.ethereum.core.Account;
import tech.pegasys.pantheon.ethereum.core.Address;
import tech.pegasys.pantheon.ethereum.core.BlockHeaderFunctions;
import tech.pegasys.pantheon.ethereum.core.BlockImporter;
Expand Down Expand Up @@ -131,7 +132,9 @@ public ProtocolSpecBuilder<T> precompileContractRegistryBuilder(
precompileContractRegistryBuilder.apply(precompiledContractConfiguration);
if (precompiledContractConfiguration.getPrivacyParameters().isEnabled()) {
MainnetPrecompiledContractRegistries.appendPrivacy(
registry, precompiledContractConfiguration);
registry, precompiledContractConfiguration, Account.DEFAULT_VERSION);
MainnetPrecompiledContractRegistries.appendPrivacy(
registry, precompiledContractConfiguration, 1);
}
return registry;
};
Expand Down Expand Up @@ -276,7 +279,8 @@ public ProtocolSpec<T> build(final ProtocolSchedule<T> protocolSchedule) {
gasCalculator, transactionValidator, contractCreationProcessor, messageCallProcessor);
Address address = Address.privacyPrecompiled(privacyParameters.getPrivacyAddress());
PrivacyPrecompiledContract privacyPrecompiledContract =
(PrivacyPrecompiledContract) precompileContractRegistry.get(address);
(PrivacyPrecompiledContract)
precompileContractRegistry.get(address, Account.DEFAULT_VERSION);
privacyPrecompiledContract.setPrivateTransactionProcessor(privateTransactionProcessor);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import tech.pegasys.pantheon.config.GenesisConfigFile;
import tech.pegasys.pantheon.controller.PantheonController;
import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair;
import tech.pegasys.pantheon.ethereum.core.Account;
import tech.pegasys.pantheon.ethereum.core.Address;
import tech.pegasys.pantheon.ethereum.core.InMemoryStorageProvider;
import tech.pegasys.pantheon.ethereum.core.MiningParametersTestBuilder;
Expand Down Expand Up @@ -72,7 +73,7 @@ public void privacyPrecompiled() throws IOException {
.getProtocolSchedule()
.getByBlockNumber(1)
.getPrecompileContractRegistry()
.get(privacyContractAddress);
.get(privacyContractAddress, Account.DEFAULT_VERSION);
assertThat(precompiledContract.getName()).isEqualTo("Privacy");
}
}

0 comments on commit ee224b1

Please sign in to comment.