Skip to content

Commit 5b1e2ed

Browse files
committed
feat: refactor method to check if wallet has enough gas
1 parent b48c4ae commit 5b1e2ed

File tree

4 files changed

+70
-3
lines changed

4 files changed

+70
-3
lines changed

src/main/java/com/iexec/commons/poco/chain/IexecHubAbstractService.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.web3j.utils.Numeric;
3434

3535
import java.io.IOException;
36+
import java.math.BigDecimal;
3637
import java.math.BigInteger;
3738
import java.util.Map;
3839
import java.util.Optional;
@@ -68,6 +69,7 @@ public abstract class IexecHubAbstractService {
6869
private final int maxRetries;
6970
private final Map<Long, ChainCategory> categories = new ConcurrentHashMap<>();
7071
private final Map<String, TaskDescription> taskDescriptions = new ConcurrentHashMap<>();
72+
private BigInteger lastKnownBalance = BigInteger.ZERO;
7173

7274
protected IexecHubAbstractService(
7375
Credentials credentials,
@@ -444,6 +446,40 @@ private void setMaxNbOfPeriodsForConsensus() {
444446
}
445447
}
446448

449+
public boolean hasEnoughGas() {
450+
// if a sidechain is used, there is no need to check if the wallet has enough gas.
451+
// if mainnet is used, the check should be done.
452+
if (web3jAbstractService.isSidechain()) {
453+
return true;
454+
}
455+
456+
final Optional<BigInteger> oWeiBalance = web3jAbstractService.getBalance(credentials.getAddress());
457+
if (oWeiBalance.isEmpty()) {
458+
log.warn("ETH balance not retrieved on chain, falling back on last known balance");
459+
}
460+
461+
final BigInteger weiBalance = oWeiBalance.orElse(lastKnownBalance);
462+
// preserve last known balance for future checks
463+
lastKnownBalance = weiBalance;
464+
final BigInteger estimateTxNb = weiBalance.divide(web3jAbstractService.getMaxTxCost());
465+
final BigDecimal balanceToShow = ChainUtils.weiToEth(weiBalance);
466+
467+
if (estimateTxNb.compareTo(BigInteger.ONE) < 0) {
468+
log.error("ETH balance is empty, please refill gas now [balance:{}, estimateTxNb:{}]", balanceToShow, estimateTxNb);
469+
return false;
470+
} else if (estimateTxNb.compareTo(BigInteger.TEN) < 0) {
471+
log.warn("ETH balance very low, should refill gas now [balance:{}, estimateTxNb:{}]", balanceToShow, estimateTxNb);
472+
} else {
473+
log.debug("ETH balance is fine [balance:{}, estimateTxNb:{}]", balanceToShow, estimateTxNb);
474+
}
475+
476+
return true;
477+
}
478+
479+
/**
480+
* @deprecated Use hasEnoughGas() instead
481+
*/
482+
@Deprecated(forRemoval = true)
447483
public boolean hasEnoughGas(String address) {
448484
return web3jAbstractService.hasEnoughGas(address);
449485
}

src/main/java/com/iexec/commons/poco/chain/Web3jAbstractService.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,15 @@ public abstract class Web3jAbstractService {
6262
private final Duration blockTime;
6363
private final float gasPriceMultiplier;
6464
private final long gasPriceCap;
65+
@Getter
6566
private final boolean isSidechain;
6667
@Getter
6768
private final Web3j web3j;
6869
@Getter
6970
private final ContractGasProvider contractGasProvider;
7071

72+
private BigInteger lastKnownBalance = BigInteger.ZERO;
73+
7174
/**
7275
* Apart from initializing usual business entities, it initializes a single
7376
* and shared web3j instance. This inner web3j instance allows to connect to
@@ -121,6 +124,10 @@ public boolean isConnected() {
121124
return false;
122125
}
123126

127+
/**
128+
* @deprecated only used from deprecated method
129+
*/
130+
@Deprecated(forRemoval = true)
124131
public static BigInteger getMaxTxCost(long gasPriceCap) {
125132
return BigInteger.valueOf(GAS_LIMIT_CAP * gasPriceCap);
126133
}
@@ -240,6 +247,10 @@ private void decodeAndThrowEvmRpcError(final Response.Error error) {
240247
throw new JsonRpcError(error.getCode(), message, null);
241248
}
242249

250+
/**
251+
* @deprecated Use IexecHubAbstractService#hasEnoughGas() instead
252+
*/
253+
@Deprecated(forRemoval = true)
243254
public boolean hasEnoughGas(String address) {
244255
// if a sidechain is used, there is no need to check if the wallet has enough gas.
245256
// if mainnet is used, the check should be done.
@@ -268,9 +279,9 @@ public boolean hasEnoughGas(String address) {
268279
return true;
269280
}
270281

271-
public Optional<BigInteger> getBalance(String address) {
282+
public Optional<BigInteger> getBalance(final String address) {
272283
try {
273-
BigInteger balance = web3j.ethGetBalance(address, DefaultBlockParameterName.LATEST).send().getBalance();
284+
final BigInteger balance = web3j.ethGetBalance(address, DefaultBlockParameterName.LATEST).send().getBalance();
274285
log.debug("{} current balance is {}", address, balance);
275286
return Optional.of(balance);
276287
} catch (IOException e) {
@@ -279,6 +290,10 @@ public Optional<BigInteger> getBalance(String address) {
279290
}
280291
}
281292

293+
public BigInteger getMaxTxCost() {
294+
return BigInteger.valueOf(GAS_LIMIT_CAP * gasPriceCap);
295+
}
296+
282297
/**
283298
* Request current gas price on the network.
284299
* <p>

src/test/java/com/iexec/commons/poco/itest/ChainTests.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,18 @@ void shouldGetAccount() {
8181
assertThat(chainAccount.getLocked()).isZero();
8282
}
8383

84+
@Test
85+
void shouldHaveEnoughGasOnBellecour() {
86+
assertThat(iexecHubService.hasEnoughGas()).isTrue();
87+
}
88+
89+
@Test
90+
void shouldHaveEnoughGasOnArbitrum() throws IOException {
91+
final Web3jTestService arbitrumWeb3j = new Web3jTestService(chainNodeAddress, 1.0f, 22_000_000_000L, false);
92+
final IexecHubTestService arbitrumHub = new IexecHubTestService(credentials, arbitrumWeb3j);
93+
assertThat(arbitrumHub.hasEnoughGas()).isTrue();
94+
}
95+
8496
@Test
8597
void shouldGetBalance() {
8698
final BigInteger balance = web3jService.getBalance(credentials.getAddress()).orElse(null);

src/test/java/com/iexec/commons/poco/itest/Web3jTestService.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@ public Web3jTestService(String chainNodeAddress) {
4242
}
4343

4444
public Web3jTestService(String chainNodeAddress, float gasPriceMultiplier, long gasPriceCap) {
45-
super(65535, chainNodeAddress, Duration.ofSeconds(BLOCK_TIME), gasPriceMultiplier, gasPriceCap, true);
45+
this(chainNodeAddress, gasPriceMultiplier, gasPriceCap, true);
46+
}
47+
48+
public Web3jTestService(String chainNodeAddress, float gasPriceMultiplier, long gasPriceCap, boolean isSidechain) {
49+
super(65535, chainNodeAddress, Duration.ofSeconds(BLOCK_TIME), gasPriceMultiplier, gasPriceCap, isSidechain);
4650
}
4751

4852
@SneakyThrows

0 commit comments

Comments
 (0)