From e1dfd4550e042644a7feca47ea2473a4c788390d Mon Sep 17 00:00:00 2001 From: Nischal Sharma Date: Mon, 20 Jan 2025 22:43:34 +0530 Subject: [PATCH] improved solution and fixed integration test Signed-off-by: Nischal Sharma --- core/src/main/java/org/web3j/tx/Contract.java | 44 ++++++++++++++--- .../tx/gas/DynamicEIP1559GasProvider.java | 15 +++++- .../org/web3j/tx/gas/DynamicGasProvider.java | 3 +- .../scenarios/DynamicGasProviderIT.java | 47 +++++++++++++++++-- 4 files changed, 95 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/org/web3j/tx/Contract.java b/core/src/main/java/org/web3j/tx/Contract.java index 2aedbae8e..d93504919 100644 --- a/core/src/main/java/org/web3j/tx/Contract.java +++ b/core/src/main/java/org/web3j/tx/Contract.java @@ -395,15 +395,31 @@ TransactionReceipt executeTransaction( ContractEIP1559GasProvider eip1559GasProvider = (ContractEIP1559GasProvider) gasProvider; if (eip1559GasProvider.isEIP1559Enabled()) { + Transaction tx; + if (constructor) { + tx = + Transaction.createContractTransaction( + this.transactionManager.getFromAddress(), + BigInteger.ONE, + gasProvider.getGasPrice(), + data); + } else { + tx = + Transaction.createFunctionCallTransaction( + this.transactionManager.getFromAddress(), + BigInteger.ONE, + gasProvider.getGasPrice(), + gasProvider.getGasLimit(), + contractAddress, + data); + } receipt = sendEIP1559( eip1559GasProvider.getChainId(), contractAddress, data, weiValue, - eip1559GasProvider.getGasLimit( - Transaction.createEthCallTransaction( - ZERO_ADDRESS, contractAddress, data)), + eip1559GasProvider.getGasLimit(tx), eip1559GasProvider.getMaxPriorityFeePerGas(), eip1559GasProvider.getMaxFeePerGas(), constructor); @@ -411,15 +427,31 @@ TransactionReceipt executeTransaction( } if (receipt == null) { + Transaction tx; + if (constructor) { + tx = + Transaction.createContractTransaction( + this.transactionManager.getFromAddress(), + BigInteger.ONE, + gasProvider.getGasPrice(), + data); + } else { + tx = + Transaction.createFunctionCallTransaction( + this.transactionManager.getFromAddress(), + BigInteger.ONE, + gasProvider.getGasPrice(), + gasProvider.getGasLimit(), + contractAddress, + data); + } receipt = send( contractAddress, data, weiValue, gasProvider.getGasPrice(), - gasProvider.getGasLimit( - Transaction.createEthCallTransaction( - ZERO_ADDRESS, contractAddress, data)), + gasProvider.getGasLimit(tx), constructor); } } catch (JsonRpcError error) { diff --git a/core/src/main/java/org/web3j/tx/gas/DynamicEIP1559GasProvider.java b/core/src/main/java/org/web3j/tx/gas/DynamicEIP1559GasProvider.java index 5ed32a37e..3fe0dc5ff 100644 --- a/core/src/main/java/org/web3j/tx/gas/DynamicEIP1559GasProvider.java +++ b/core/src/main/java/org/web3j/tx/gas/DynamicEIP1559GasProvider.java @@ -18,6 +18,7 @@ import org.web3j.protocol.Web3j; import org.web3j.protocol.core.methods.request.Transaction; +import org.web3j.protocol.core.methods.response.EthEstimateGas; import org.web3j.protocol.core.methods.response.EthGasPrice; import org.web3j.protocol.core.methods.response.EthMaxPriorityFeePerGas; @@ -26,6 +27,7 @@ public class DynamicEIP1559GasProvider implements ContractEIP1559GasProvider, Pr private long chainId; private final Priority priority; private final BigDecimal customMultiplier; + public static final BigInteger GAS_LIMIT = BigInteger.valueOf(9_000_000); public DynamicEIP1559GasProvider(Web3j web3j, long chainId) { this(web3j, chainId, Priority.NORMAL); @@ -81,12 +83,21 @@ public BigInteger getGasPrice() { @Override public BigInteger getGasLimit(Transaction transaction) { - return null; + try { + EthEstimateGas ethEstimateGas = web3j.ethEstimateGas(transaction).send(); + if (ethEstimateGas.hasError()) { + throw new RuntimeException( + "Error estimating gas limit: " + ethEstimateGas.getError().getMessage()); + } + return ethEstimateGas.getAmountUsed(); + } catch (Exception e) { + throw new RuntimeException("Failed to estimate gas limit", e); + } } @Override public BigInteger getGasLimit() { - return null; + return GAS_LIMIT; } private BigInteger fetchCurrentGasPrice() { diff --git a/core/src/main/java/org/web3j/tx/gas/DynamicGasProvider.java b/core/src/main/java/org/web3j/tx/gas/DynamicGasProvider.java index a1bda9d2f..6ecca9e3c 100644 --- a/core/src/main/java/org/web3j/tx/gas/DynamicGasProvider.java +++ b/core/src/main/java/org/web3j/tx/gas/DynamicGasProvider.java @@ -25,6 +25,7 @@ public class DynamicGasProvider implements ContractGasProvider, PriorityGasProvi private final Web3j web3j; private final Priority priority; private final BigDecimal customMultiplier; + public static final BigInteger GAS_LIMIT = BigInteger.valueOf(9_000_000); public DynamicGasProvider(Web3j web3j) { this(web3j, Priority.NORMAL); @@ -47,7 +48,7 @@ public BigInteger getGasPrice() { @Override public BigInteger getGasLimit() { - return null; + return GAS_LIMIT; } public BigInteger getGasLimit(Transaction transaction) { diff --git a/integration-tests/src/test/java/org/web3j/protocol/scenarios/DynamicGasProviderIT.java b/integration-tests/src/test/java/org/web3j/protocol/scenarios/DynamicGasProviderIT.java index bc22916d1..9169ff2e9 100644 --- a/integration-tests/src/test/java/org/web3j/protocol/scenarios/DynamicGasProviderIT.java +++ b/integration-tests/src/test/java/org/web3j/protocol/scenarios/DynamicGasProviderIT.java @@ -12,6 +12,7 @@ */ package org.web3j.protocol.scenarios; +import java.math.BigDecimal; import java.math.BigInteger; import org.junit.jupiter.api.BeforeAll; @@ -23,6 +24,7 @@ import org.web3j.test.contract.HumanStandardToken; import org.web3j.tx.gas.ContractGasProvider; import org.web3j.tx.gas.DynamicGasProvider; +import org.web3j.tx.gas.PriorityGasProvider; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -31,6 +33,10 @@ public class DynamicGasProviderIT extends Scenario { static ContractGasProvider dynamicGasProvider; static String contractAddress; + static final String TOKEN_NAME = "Alice Token"; + static final String TOKEN_SYMBOL = "ATK"; + static final BigInteger TOKEN_DECIMALS = BigInteger.valueOf(18L); + static final BigInteger TOKEN_SUPPLY = BigInteger.valueOf(10_000_000L); @BeforeAll static void setUp(Web3j web3j) throws Exception { @@ -54,7 +60,38 @@ public void callSmartContractFunction() throws Exception { HumanStandardToken humanStandardToken = HumanStandardToken.load(contractAddress, web3j, ALICE, dynamicGasProvider); - assertEquals(humanStandardToken.name().send(), "Alice Token"); + assertEquals(humanStandardToken.name().send(), TOKEN_NAME); + + assertNotNull(humanStandardToken.transfer(BOB.getAddress(), BigInteger.ONE).send()); + assertEquals(humanStandardToken.balanceOf(BOB.getAddress()).send(), BigInteger.ONE); + } + + @Test + public void callSmartContractFunctionWithPriority() throws Exception { + DynamicGasProvider fastDynamicGasProvider = + new DynamicGasProvider(web3j, PriorityGasProvider.Priority.FAST); + DynamicGasProvider slowDynamicGasProvider = + new DynamicGasProvider(web3j, PriorityGasProvider.Priority.SLOW); + DynamicGasProvider customDynamicGasProvider = + new DynamicGasProvider( + web3j, PriorityGasProvider.Priority.CUSTOM, BigDecimal.valueOf(1.5)); + + assertEquals( + dynamicGasProvider.getGasPrice().multiply(BigInteger.TWO), + fastDynamicGasProvider.getGasPrice()); + assertEquals( + dynamicGasProvider.getGasPrice().divide(BigInteger.TWO), + slowDynamicGasProvider.getGasPrice()); + assertEquals( + new BigDecimal(dynamicGasProvider.getGasPrice()) + .multiply(BigDecimal.valueOf(1.5)) + .toBigInteger(), + customDynamicGasProvider.getGasPrice()); + + HumanStandardToken humanStandardToken = + HumanStandardToken.load(contractAddress, web3j, ALICE, fastDynamicGasProvider); + + assertEquals(humanStandardToken.name().send(), TOKEN_NAME); assertNotNull(humanStandardToken.transfer(BOB.getAddress(), BigInteger.ONE).send()); assertEquals(humanStandardToken.balanceOf(BOB.getAddress()).send(), BigInteger.ONE); @@ -65,10 +102,10 @@ private static String sendTransaction() throws Exception { web3j, ALICE, dynamicGasProvider, - BigInteger.valueOf(100L), - "Alice Token", - BigInteger.valueOf(18L), - "ATK") + TOKEN_SUPPLY, + TOKEN_NAME, + TOKEN_DECIMALS, + TOKEN_SYMBOL) .send() .getContractAddress(); }