Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.web3j.utils.Numeric;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Map;
import java.util.Optional;
Expand Down Expand Up @@ -68,6 +69,7 @@
private final int maxRetries;
private final Map<Long, ChainCategory> categories = new ConcurrentHashMap<>();
private final Map<String, TaskDescription> taskDescriptions = new ConcurrentHashMap<>();
private BigInteger lastKnownBalance = BigInteger.ZERO;

protected IexecHubAbstractService(
Credentials credentials,
Expand Down Expand Up @@ -444,7 +446,41 @@
}
}

public boolean hasEnoughGas() {
// if a sidechain is used, there is no need to check if the wallet has enough gas.
// if mainnet is used, the check should be done.
if (web3jAbstractService.isSidechain()) {
return true;
}

final Optional<BigInteger> oWeiBalance = web3jAbstractService.getBalance(credentials.getAddress());
if (oWeiBalance.isEmpty()) {
log.warn("ETH balance not retrieved on chain, falling back on last known balance");
}

final BigInteger weiBalance = oWeiBalance.orElse(lastKnownBalance);
// preserve last known balance for future checks
lastKnownBalance = weiBalance;
final BigInteger estimateTxNb = weiBalance.divide(web3jAbstractService.getMaxTxCost());
final BigDecimal balanceToShow = ChainUtils.weiToEth(weiBalance);

if (estimateTxNb.compareTo(BigInteger.ONE) < 0) {
log.error("ETH balance is empty, please refill gas now [balance:{}, estimateTxNb:{}]", balanceToShow, estimateTxNb);
return false;
} else if (estimateTxNb.compareTo(BigInteger.TEN) < 0) {
log.warn("ETH balance very low, should refill gas now [balance:{}, estimateTxNb:{}]", balanceToShow, estimateTxNb);
} else {
log.debug("ETH balance is fine [balance:{}, estimateTxNb:{}]", balanceToShow, estimateTxNb);
}

return true;
}

/**
* @deprecated Use hasEnoughGas() instead
*/
@Deprecated(forRemoval = true)
public boolean hasEnoughGas(String address) {

Check warning on line 483 in src/main/java/com/iexec/commons/poco/chain/IexecHubAbstractService.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Do not forget to remove this deprecated code someday.

See more on https://sonarcloud.io/project/issues?id=com.iexec.commons%3Aiexec-commons-poco&issues=AZrvSt2ckXnx3O3DiNIE&open=AZrvSt2ckXnx3O3DiNIE&pullRequest=165
return web3jAbstractService.hasEnoughGas(address);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
private final Duration blockTime;
private final float gasPriceMultiplier;
private final long gasPriceCap;
@Getter
private final boolean isSidechain;
@Getter
private final Web3j web3j;
Expand Down Expand Up @@ -121,7 +122,11 @@
return false;
}

/**
* @deprecated only used from deprecated method
*/
@Deprecated(forRemoval = true)
public static BigInteger getMaxTxCost(long gasPriceCap) {

Check warning on line 129 in src/main/java/com/iexec/commons/poco/chain/Web3jAbstractService.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Do not forget to remove this deprecated code someday.

See more on https://sonarcloud.io/project/issues?id=com.iexec.commons%3Aiexec-commons-poco&issues=AZrvSt0YkXnx3O3DiNIB&open=AZrvSt0YkXnx3O3DiNIB&pullRequest=165
return BigInteger.valueOf(GAS_LIMIT_CAP * gasPriceCap);
}

Expand Down Expand Up @@ -240,7 +245,11 @@
throw new JsonRpcError(error.getCode(), message, null);
}

/**
* @deprecated Use IexecHubAbstractService#hasEnoughGas() instead
*/
@Deprecated(forRemoval = true)
public boolean hasEnoughGas(String address) {

Check warning on line 252 in src/main/java/com/iexec/commons/poco/chain/Web3jAbstractService.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Do not forget to remove this deprecated code someday.

See more on https://sonarcloud.io/project/issues?id=com.iexec.commons%3Aiexec-commons-poco&issues=AZrvSt0YkXnx3O3DiNIC&open=AZrvSt0YkXnx3O3DiNIC&pullRequest=165
// if a sidechain is used, there is no need to check if the wallet has enough gas.
// if mainnet is used, the check should be done.
if (isSidechain) {
Expand Down Expand Up @@ -268,9 +277,9 @@
return true;
}

public Optional<BigInteger> getBalance(String address) {
public Optional<BigInteger> getBalance(final String address) {
try {
BigInteger balance = web3j.ethGetBalance(address, DefaultBlockParameterName.LATEST).send().getBalance();
final BigInteger balance = web3j.ethGetBalance(address, DefaultBlockParameterName.LATEST).send().getBalance();
log.debug("{} current balance is {}", address, balance);
return Optional.of(balance);
} catch (IOException e) {
Expand All @@ -279,6 +288,10 @@
}
}

public BigInteger getMaxTxCost() {
return BigInteger.valueOf(GAS_LIMIT_CAP * gasPriceCap);
}

/**
* Request current gas price on the network.
* <p>
Expand Down
21 changes: 21 additions & 0 deletions src/test/java/com/iexec/commons/poco/itest/ChainTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.Keys;
import org.web3j.crypto.WalletUtils;
import org.web3j.crypto.exception.CipherException;

Expand Down Expand Up @@ -81,6 +82,26 @@
assertThat(chainAccount.getLocked()).isZero();
}

@Test
void shouldHaveEnoughGasOnBellecour() {
assertThat(iexecHubService.hasEnoughGas()).isTrue();
}

@Test
void shouldHaveEnoughGasOnArbitrum() throws IOException {
final Web3jTestService arbitrumWeb3j = new Web3jTestService(chainNodeAddress, 1.0f, 22_000_000_000L, false);
final IexecHubTestService arbitrumHub = new IexecHubTestService(credentials, arbitrumWeb3j);
assertThat(arbitrumHub.hasEnoughGas()).isTrue();
}

@Test
void shouldNotHaveEnoughGasOnArbitrum() throws Exception {
final Credentials newCredentials = Credentials.create(Keys.createEcKeyPair());
final Web3jTestService arbitrumWeb3j = new Web3jTestService(chainNodeAddress, 1.0f, 22_000_000_000L, false);
final IexecHubTestService arbitrumHub = new IexecHubTestService(newCredentials, arbitrumWeb3j);
assertThat(arbitrumHub.hasEnoughGas()).isFalse();
}

@Test
void shouldGetBalance() {
final BigInteger balance = web3jService.getBalance(credentials.getAddress()).orElse(null);
Expand Down Expand Up @@ -173,7 +194,7 @@

@Test
void shouldHaveEnoughGas() {
assertThat(web3jService.hasEnoughGas(credentials.getAddress())).isTrue();

Check warning on line 197 in src/test/java/com/iexec/commons/poco/itest/ChainTests.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this call to a deprecated method, it has been marked for removal.

See more on https://sonarcloud.io/project/issues?id=com.iexec.commons%3Aiexec-commons-poco&issues=AZrvStyIkXnx3O3DiNIA&open=AZrvStyIkXnx3O3DiNIA&pullRequest=165
}

// region deal and task
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ public Web3jTestService(String chainNodeAddress) {
}

public Web3jTestService(String chainNodeAddress, float gasPriceMultiplier, long gasPriceCap) {
super(65535, chainNodeAddress, Duration.ofSeconds(BLOCK_TIME), gasPriceMultiplier, gasPriceCap, true);
this(chainNodeAddress, gasPriceMultiplier, gasPriceCap, true);
}

public Web3jTestService(String chainNodeAddress, float gasPriceMultiplier, long gasPriceCap, boolean isSidechain) {
super(65535, chainNodeAddress, Duration.ofSeconds(BLOCK_TIME), gasPriceMultiplier, gasPriceCap, isSidechain);
}

@SneakyThrows
Expand Down