diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetPrecompiledContractRegistries.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetPrecompiledContractRegistries.java index ffbbac2bfc..84245f0d2a 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetPrecompiledContractRegistries.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/MainnetPrecompiledContractRegistries.java @@ -12,6 +12,8 @@ */ package tech.pegasys.pantheon.ethereum.mainnet; +import static tech.pegasys.pantheon.ethereum.mainnet.MainnetProtocolSpecs.ISTANBUL_ACCOUNT_VERSION; + import tech.pegasys.pantheon.ethereum.core.Account; import tech.pegasys.pantheon.ethereum.core.Address; import tech.pegasys.pantheon.ethereum.mainnet.precompiles.AltBN128AddPrecompiledContract; @@ -59,13 +61,17 @@ public abstract class MainnetPrecompiledContractRegistries { accountVersion, new BigIntegerModularExponentiationPrecompiledContract(gasCalculator)); registry.put( - Address.ALTBN128_ADD, accountVersion, new AltBN128AddPrecompiledContract(gasCalculator)); + Address.ALTBN128_ADD, + accountVersion, + AltBN128AddPrecompiledContract.byzantium(gasCalculator)); registry.put( - Address.ALTBN128_MUL, accountVersion, new AltBN128MulPrecompiledContract(gasCalculator)); + Address.ALTBN128_MUL, + accountVersion, + AltBN128MulPrecompiledContract.byzantium(gasCalculator)); registry.put( Address.ALTBN128_PAIRING, accountVersion, - new AltBN128PairingPrecompiledContract(gasCalculator)); + AltBN128PairingPrecompiledContract.byzantium(gasCalculator)); } public static PrecompileContractRegistry byzantium( @@ -81,7 +87,24 @@ public abstract class MainnetPrecompiledContractRegistries { final PrecompileContractRegistry registry = new PrecompileContractRegistry(); populateForByzantium( registry, precompiledContractConfiguration.getGasCalculator(), Account.DEFAULT_VERSION); - populateForByzantium(registry, precompiledContractConfiguration.getGasCalculator(), 1); + populateForByzantium( + registry, precompiledContractConfiguration.getGasCalculator(), ISTANBUL_ACCOUNT_VERSION); + registry.put( + Address.ALTBN128_ADD, + ISTANBUL_ACCOUNT_VERSION, + AltBN128AddPrecompiledContract.istanbul( + precompiledContractConfiguration.getGasCalculator())); + registry.put( + Address.ALTBN128_MUL, + ISTANBUL_ACCOUNT_VERSION, + AltBN128MulPrecompiledContract.istanbul( + precompiledContractConfiguration.getGasCalculator())); + registry.put( + Address.ALTBN128_PAIRING, + ISTANBUL_ACCOUNT_VERSION, + AltBN128PairingPrecompiledContract.istanbul( + precompiledContractConfiguration.getGasCalculator())); + return registry; } diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/precompiles/AltBN128AddPrecompiledContract.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/precompiles/AltBN128AddPrecompiledContract.java index 7ab96a4261..b6a82a9bdb 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/precompiles/AltBN128AddPrecompiledContract.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/precompiles/AltBN128AddPrecompiledContract.java @@ -26,13 +26,24 @@ import java.util.Arrays; public class AltBN128AddPrecompiledContract extends AbstractPrecompiledContract { - public AltBN128AddPrecompiledContract(final GasCalculator gasCalculator) { + private final Gas gasCost; + + private AltBN128AddPrecompiledContract(final GasCalculator gasCalculator, final Gas gasCost) { super("AltBN128Add", gasCalculator); + this.gasCost = gasCost; + } + + public static AltBN128AddPrecompiledContract byzantium(final GasCalculator gasCalculator) { + return new AltBN128AddPrecompiledContract(gasCalculator, Gas.of(500)); + } + + public static AltBN128AddPrecompiledContract istanbul(final GasCalculator gasCalculator) { + return new AltBN128AddPrecompiledContract(gasCalculator, Gas.of(150)); } @Override public Gas gasRequirement(final BytesValue input) { - return Gas.of(500); + return gasCost; } @Override diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/precompiles/AltBN128MulPrecompiledContract.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/precompiles/AltBN128MulPrecompiledContract.java index 6cc2a009cf..65936dacb2 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/precompiles/AltBN128MulPrecompiledContract.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/precompiles/AltBN128MulPrecompiledContract.java @@ -30,13 +30,24 @@ public class AltBN128MulPrecompiledContract extends AbstractPrecompiledContract new BigInteger( "115792089237316195423570985008687907853269984665640564039457584007913129639935"); - public AltBN128MulPrecompiledContract(final GasCalculator gasCalculator) { - super("AltBn128Mul", gasCalculator); + private final Gas gasCost; + + private AltBN128MulPrecompiledContract(final GasCalculator gasCalculator, final Gas gasCost) { + super("AltBN128Mul", gasCalculator); + this.gasCost = gasCost; + } + + public static AltBN128MulPrecompiledContract byzantium(final GasCalculator gasCalculator) { + return new AltBN128MulPrecompiledContract(gasCalculator, Gas.of(40_000)); + } + + public static AltBN128MulPrecompiledContract istanbul(final GasCalculator gasCalculator) { + return new AltBN128MulPrecompiledContract(gasCalculator, Gas.of(8_000)); } @Override public Gas gasRequirement(final BytesValue input) { - return Gas.of(40_000L); + return gasCost; } @Override diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/precompiles/AltBN128PairingPrecompiledContract.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/precompiles/AltBN128PairingPrecompiledContract.java index 2bdc357ddc..471f60b221 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/precompiles/AltBN128PairingPrecompiledContract.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/mainnet/precompiles/AltBN128PairingPrecompiledContract.java @@ -41,14 +41,28 @@ public class AltBN128PairingPrecompiledContract extends AbstractPrecompiledContr BytesValue.fromHexString( "0x0000000000000000000000000000000000000000000000000000000000000001"); - public AltBN128PairingPrecompiledContract(final GasCalculator gasCalculator) { + private final Gas pairingGasCost; + private final Gas baseGasCost; + + private AltBN128PairingPrecompiledContract( + final GasCalculator gasCalculator, final Gas pairingGasCost, final Gas baseGasCost) { super("AltBN128Pairing", gasCalculator); + this.pairingGasCost = pairingGasCost; + this.baseGasCost = baseGasCost; + } + + public static AltBN128PairingPrecompiledContract byzantium(final GasCalculator gasCalculator) { + return new AltBN128PairingPrecompiledContract(gasCalculator, Gas.of(80_000), Gas.of(100_000)); + } + + public static AltBN128PairingPrecompiledContract istanbul(final GasCalculator gasCalculator) { + return new AltBN128PairingPrecompiledContract(gasCalculator, Gas.of(34_000), Gas.of(45_000)); } @Override public Gas gasRequirement(final BytesValue input) { final int parameters = input.size() / PARAMETER_LENGTH; - return Gas.of(80_000L).times(Gas.of(parameters)).plus(Gas.of(100_000L)); + return pairingGasCost.times(parameters).plus(baseGasCost); } @Override diff --git a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/mainnet/precompiles/AltBN128PairingPrecompiledContractTest.java b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/mainnet/precompiles/AltBN128PairingPrecompiledContractTest.java index a3ebc0e59d..8d061d1225 100644 --- a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/mainnet/precompiles/AltBN128PairingPrecompiledContractTest.java +++ b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/mainnet/precompiles/AltBN128PairingPrecompiledContractTest.java @@ -14,6 +14,7 @@ package tech.pegasys.pantheon.ethereum.mainnet.precompiles; import static org.assertj.core.api.Assertions.assertThat; +import tech.pegasys.pantheon.ethereum.core.Gas; import tech.pegasys.pantheon.ethereum.vm.GasCalculator; import tech.pegasys.pantheon.ethereum.vm.MessageFrame; import tech.pegasys.pantheon.util.bytes.BytesValue; @@ -29,11 +30,20 @@ public class AltBN128PairingPrecompiledContractTest { @Mock MessageFrame messageFrame; @Mock GasCalculator gasCalculator; - final AltBN128PairingPrecompiledContract precompile = - new AltBN128PairingPrecompiledContract(gasCalculator); + + private final AltBN128PairingPrecompiledContract byzantiumContract = + AltBN128PairingPrecompiledContract.byzantium(gasCalculator); + private final AltBN128PairingPrecompiledContract istanbulContract = + AltBN128PairingPrecompiledContract.istanbul(gasCalculator); @Test public void compute_validPoints() { + final BytesValue input = validPointBytes(); + final BytesValue result = byzantiumContract.compute(input, messageFrame); + assertThat(result).isEqualTo(AltBN128PairingPrecompiledContract.TRUE); + } + + public BytesValue validPointBytes() { final BytesValue g1Point0 = BytesValues.concatenate( BytesValue.fromHexString( @@ -67,9 +77,7 @@ public class AltBN128PairingPrecompiledContractTest { BytesValue.fromHexString( "0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa")); - final BytesValue input = BytesValues.concatenate(g1Point0, g2Point0, g1Point1, g2Point1); - final BytesValue result = precompile.compute(input, messageFrame); - assertThat(result).isEqualTo(AltBN128PairingPrecompiledContract.TRUE); + return BytesValues.concatenate(g1Point0, g2Point0, g1Point1, g2Point1); } @Test @@ -108,7 +116,17 @@ public class AltBN128PairingPrecompiledContractTest { "0x1fbf8045ce3e79b5cde4112d38bcd0efbdb1295d2eefdf58151ae309d7ded7db")); final BytesValue input = BytesValues.concatenate(g1Point0, g2Point0, g1Point1, g2Point1); - final BytesValue result = precompile.compute(input, messageFrame); + final BytesValue result = byzantiumContract.compute(input, messageFrame); assertThat(result).isNull(); } + + @Test + public void gasPrice_byzantium() { + assertThat(byzantiumContract.gasRequirement(validPointBytes())).isEqualTo(Gas.of(260_000)); + } + + @Test + public void gasPrice_istanbul() { + assertThat(istanbulContract.gasRequirement(validPointBytes())).isEqualTo(Gas.of(113_000)); + } }