Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework gas fetch methods #3360

Merged
merged 1 commit into from
Feb 19, 2024
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
5 changes: 3 additions & 2 deletions app/src/main/java/com/alphawallet/app/di/ToolsModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.alphawallet.app.C;
import com.alphawallet.app.interact.WalletConnectInteract;
import com.alphawallet.app.repository.PreferenceRepositoryType;
import com.alphawallet.app.service.GasService;
import com.alphawallet.app.service.RealmManager;
import com.alphawallet.app.walletconnect.AWWalletConnectClient;
import com.google.gson.Gson;
Expand Down Expand Up @@ -54,8 +55,8 @@ RealmManager provideRealmManager()

@Singleton
@Provides
AWWalletConnectClient provideAWWalletConnectClient(@ApplicationContext Context context, WalletConnectInteract walletConnectInteract, PreferenceRepositoryType preferenceRepositoryType)
AWWalletConnectClient provideAWWalletConnectClient(@ApplicationContext Context context, WalletConnectInteract walletConnectInteract, PreferenceRepositoryType preferenceRepositoryType, GasService gasService)
{
return new AWWalletConnectClient(context, walletConnectInteract, preferenceRepositoryType);
return new AWWalletConnectClient(context, walletConnectInteract, preferenceRepositoryType, gasService);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ public class ERC721Token extends Token
{
private final Map<BigInteger, NFTAsset> tokenBalanceAssets;
private static final Map<String, Boolean> balanceChecks = new ConcurrentHashMap<>();
private boolean batchProcessingError;

public ERC721Token(TokenInfo tokenInfo, Map<BigInteger, NFTAsset> balanceList, BigDecimal balance, long blancaTime, String networkName, ContractType type)
{
Expand All @@ -90,7 +89,6 @@ public ERC721Token(TokenInfo tokenInfo, Map<BigInteger, NFTAsset> balanceList, B
}
setInterfaceSpec(type);
group = TokenGroup.NFT;
batchProcessingError = false;
}

@Override
Expand Down Expand Up @@ -419,7 +417,7 @@ private void updateEnumerableBalance(Web3j web3j, Realm realm) throws IOExceptio
//find tokenIds held
long currentBalance = balance != null ? balance.longValue() : 0;

if (EthereumNetworkBase.getBatchProcessingLimit(tokenInfo.chainId) > 0 && !batchProcessingError && currentBalance > 1) //no need to do batch query for 1
if (EthereumNetworkBase.getBatchProcessingLimit(tokenInfo.chainId) > 0 && currentBalance > 1) //no need to do batch query for 1
{
updateEnumerableBatchBalance(web3j, currentBalance, tokenIdsHeld, realm);
}
Expand Down Expand Up @@ -457,19 +455,14 @@ private void updateEnumerableBatchBalance(Web3j web3j, long currentBalance, Hash
//do final call
handleEnumerableRequests(requests, tokenIdsHeld);
}

if (batchProcessingError)
{
updateEnumerableBalance(web3j, realm);
}
}

private void handleEnumerableRequests(BatchRequest requests, HashSet<BigInteger> tokenIdsHeld) throws IOException
{
BatchResponse responses = requests.send();
if (responses.getResponses().size() != requests.getRequests().size())
{
batchProcessingError = true;
EthereumNetworkBase.setBatchProcessingError(tokenInfo.chainId);
return;
}

Expand Down Expand Up @@ -622,7 +615,7 @@ public HashSet<BigInteger> processLogsAndStoreTransferEvents(EthLog receiveLogs,
private HashSet<BigInteger> checkBalances(Web3j web3j, HashSet<BigInteger> eventIds) throws IOException
{
HashSet<BigInteger> heldTokens = new HashSet<>();
if (EthereumNetworkBase.getBatchProcessingLimit(tokenInfo.chainId) > 0 && !batchProcessingError && eventIds.size() > 1) return checkBatchBalances(web3j, eventIds);
if (EthereumNetworkBase.getBatchProcessingLimit(tokenInfo.chainId) > 0 && eventIds.size() > 1) return checkBatchBalances(web3j, eventIds);

for (BigInteger tokenId : eventIds)
{
Expand Down Expand Up @@ -659,14 +652,7 @@ private HashSet<BigInteger> checkBatchBalances(Web3j web3j, HashSet<BigInteger>
handleRequests(requests, balanceIds, heldTokens);
}

if (batchProcessingError)
{
return checkBalances(web3j, eventIds);
}
else
{
return heldTokens;
}
return heldTokens;
}

private void handleRequests(BatchRequest requests, List<BigInteger> balanceIds, HashSet<BigInteger> heldTokens) throws IOException
Expand All @@ -675,7 +661,7 @@ private void handleRequests(BatchRequest requests, List<BigInteger> balanceIds,
BatchResponse responses = requests.send();
if (responses.getResponses().size() != requests.getRequests().size())
{
batchProcessingError = true;
EthereumNetworkBase.setBatchProcessingError(tokenInfo.chainId);
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,11 @@ else if (testnetList.contains(chainId))
public static final int INFURA_BATCH_LIMIT = 512;
public static final String INFURA_DOMAIN = "infura.io";

public static void setBatchProcessingError(long chainId)
{
batchProcessingLimitMap.put(chainId, 0);
}

//TODO: Refactor when we bump the version of java to allow switch on Long (Finally!!)
//Also TODO: add a test to check these batch limits of each chain we support
private static int batchProcessingLimit(long chainId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static com.alphawallet.ethereum.EthereumNetworkBase.MAINNET_ID;
import static com.alphawallet.ethereum.EthereumNetworkBase.OKX_ID;
import static com.alphawallet.ethereum.EthereumNetworkBase.POLYGON_TEST_ID;
import static org.web3j.protocol.core.methods.request.Transaction.createEthCallTransaction;
import static java.util.Arrays.asList;

Expand Down Expand Up @@ -95,7 +96,9 @@ public class TokenRepository implements TokenRepositoryType {
public static final BigInteger INTERFACE_BALANCES_721_TICKET = new BigInteger ("c84aae17", 16);
public static final BigInteger INTERFACE_SUPERRARE = new BigInteger ("5b5e139f", 16);
public static final BigInteger INTERFACE_ERC1155 = new BigInteger("d9b67a26", 16);
public static final BigInteger INTERFACE_ERC20 = new BigInteger("36372b07", 16);
public static final BigInteger INTERFACE_ERC721_ENUMERABLE = new BigInteger("780e9d63", 16);
public static final BigInteger INTERFACE_ERC404 = new BigInteger("b374afc4", 16);

private static final int NODE_COMMS_ERROR = -1;
private static final int CONTRACT_BALANCE_NULL = -2;
Expand Down Expand Up @@ -1219,6 +1222,10 @@ else if (getContractData(network, tokenInfo.address, supportsInterface(INTERFACE
returnType = ContractType.ERC721_ENUMERABLE;
else if (getContractData(network, tokenInfo.address, supportsInterface(INTERFACE_OFFICIAL_ERC721), Boolean.TRUE))
returnType = ContractType.ERC721;
else if (getContractData(network, tokenInfo.address, supportsInterface(INTERFACE_ERC20), Boolean.TRUE))
returnType = ContractType.ERC20;
else if (getContractData(network, tokenInfo.address, supportsInterface(INTERFACE_ERC404), Boolean.TRUE))
returnType = ContractType.ERC20;
else if (getContractData(network, tokenInfo.address, supportsInterface(INTERFACE_SUPERRARE), Boolean.TRUE))
returnType = ContractType.ERC721;
else if (getContractData(network, tokenInfo.address, supportsInterface(INTERFACE_ERC1155), Boolean.TRUE))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public RawTransaction formatRawTransaction(Web3Transaction w3Tx, long nonce, lon
if (w3Tx.isLegacyTransaction())
{
return formatRawTransaction(w3Tx.getTransactionDestination().toString(), w3Tx.value, w3Tx.gasPrice, w3Tx.gasLimit, nonce,
!TextUtils.isEmpty(w3Tx.payload) ? Numeric.hexStringToByteArray(w3Tx.payload) : new byte[0]);
!TextUtils.isEmpty(w3Tx.payload) ? Numeric.hexStringToByteArray(w3Tx.payload) : new byte[0], w3Tx.isConstructor());
}
else
{
Expand Down Expand Up @@ -252,11 +252,11 @@ private Single<BigInteger> getNonceForTransaction(Web3j web3j, String wallet, lo
/**
* Format a legacy transaction
*/
private RawTransaction formatRawTransaction(String toAddress, BigInteger amount, BigInteger gasPrice, BigInteger gasLimit, long nonce, byte[] data)
private RawTransaction formatRawTransaction(String toAddress, BigInteger amount, BigInteger gasPrice, BigInteger gasLimit, long nonce, byte[] data, boolean isConstructor)
{
String dataStr = data != null ? Numeric.toHexString(data) : "";

if (TextUtils.isEmpty(toAddress)) //This transaction is a constructor
if (isConstructor)
{
return RawTransaction.createContractTransaction(
BigInteger.valueOf(nonce),
Expand Down
48 changes: 43 additions & 5 deletions app/src/main/java/com/alphawallet/app/service/GasService.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.alphawallet.app.entity.GasPriceSpread;
import com.alphawallet.app.entity.NetworkInfo;
import com.alphawallet.app.entity.SuggestEIP1559Kt;
import com.alphawallet.app.entity.TXSpeed;
import com.alphawallet.app.entity.Wallet;
import com.alphawallet.app.entity.tokens.Token;
import com.alphawallet.app.repository.EthereumNetworkBase;
Expand All @@ -27,6 +28,7 @@
import com.alphawallet.app.repository.HttpServiceHelper;
import com.alphawallet.app.repository.KeyProvider;
import com.alphawallet.app.repository.KeyProviderFactory;
import com.alphawallet.app.repository.TokenRepository;
import com.alphawallet.app.repository.entity.Realm1559Gas;
import com.alphawallet.app.repository.entity.RealmGasSpread;
import com.alphawallet.app.web3.entity.Web3Transaction;
Expand Down Expand Up @@ -147,7 +149,7 @@ private void fetchCurrentGasPrice()
.isDisposed();

//also update EIP1559 if required and we haven't previously determined there's no EIP1559 support
getEIP1559FeeStructure()
getEIP1559FeeStructure(currentChainId)
.map(result -> updateEIP1559Realm(result, currentChainId))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
Expand Down Expand Up @@ -217,11 +219,16 @@ else if (EthereumNetworkRepository.hasGasOverride(currentChainId))
}
else
{
return Single.fromCallable(() -> web3j.ethGasPrice().send())
return getNodeEstimate(currentChainId)
.map(price -> updateGasPrice(price, currentChainId, updated));
}
}

private Single<EthGasPrice> getNodeEstimate(long chainId)
{
return Single.fromCallable(() -> TokenRepository.getWeb3jService(chainId).ethGasPrice().send());
}

private Boolean updateGasPrice(EthGasPrice ethGasPrice, long chainId, boolean databaseUpdated)
{
currentGasPrice = ethGasPrice.getGasPrice();
Expand Down Expand Up @@ -295,6 +302,37 @@ private void updateRealm(final GasPriceSpread oracleResult, final long chainId)
}
}

//If for whatever reason gasprice hasn't been fetched or is out of date, use a manual fetch to ensure process goes through.
public Single<EIP1559FeeOracleResult> fetchGasPrice(long chainId, boolean use1559Gas)
{
//fetch relevant average setting
if (use1559Gas)
{
return getEIP1559FeeStructure(chainId)
.map(result -> {
//select average
EIP1559FeeOracleResult standard = (result != null && result.containsKey(TXSpeed.STANDARD)) ? result.get(TXSpeed.STANDARD) : null;
if (standard != null)
{
return standard;
}
else
{
//return legacy calc
EthGasPrice gasPrice = getNodeEstimate(chainId).blockingGet();
return new EIP1559FeeOracleResult(BigInteger.ZERO, BigInteger.ZERO, gasPrice.getGasPrice());
}
});
}
else
{
//get legacy gas
return getNodeEstimate(chainId)
.map(result -> new EIP1559FeeOracleResult(result.getGasPrice(), BigInteger.ZERO, BigInteger.ZERO));

}
}

private boolean updateEIP1559Realm(final Map<Integer, EIP1559FeeOracleResult> result, final long chainId)
{
boolean succeeded = true;
Expand Down Expand Up @@ -420,10 +458,10 @@ private Single<EthEstimateGas> ethEstimateGas(long chainId, String fromAddress,
return Single.fromCallable(() -> web3j.ethEstimateGas(transaction).send());
}

private Single<Map<Integer, EIP1559FeeOracleResult>> getEIP1559FeeStructure()
private Single<Map<Integer, EIP1559FeeOracleResult>> getEIP1559FeeStructure(long chainId)
{
return InfuraGasAPI.get1559GasEstimates(currentChainId, httpClient)
.flatMap(result -> BlockNativeGasAPI.get(httpClient).get1559GasEstimates(result, currentChainId))
return InfuraGasAPI.get1559GasEstimates(chainId, httpClient)
.flatMap(result -> BlockNativeGasAPI.get(httpClient).get1559GasEstimates(result, chainId))
.flatMap(this::useCalculationIfRequired); //if interface doesn't have blocknative API then use calculation method
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -579,4 +579,10 @@ public WalletType getWalletType()
{
return wallet.type;
}

@Override
public GasService getGasService()
{
return viewModel.getGasService();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
import com.alphawallet.app.repository.TokenRepository;
import com.alphawallet.app.repository.TokensRealmSource;
import com.alphawallet.app.repository.entity.RealmToken;
import com.alphawallet.app.service.GasService;
import com.alphawallet.app.service.WalletConnectService;
import com.alphawallet.app.ui.QRScanning.QRScannerActivity;
import com.alphawallet.app.ui.widget.OnDappHomeNavClickListener;
Expand Down Expand Up @@ -120,13 +121,13 @@
import com.alphawallet.token.entity.SalesOrderMalformed;
import com.alphawallet.token.entity.SignMessageType;
import com.alphawallet.token.entity.Signable;
import org.web3j.utils.Numeric;
import com.alphawallet.token.tools.ParseMagicLink;

import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.methods.response.EthCall;
import org.web3j.utils.Numeric;

import java.io.ByteArrayOutputStream;
import java.io.File;
Expand Down Expand Up @@ -1236,6 +1237,12 @@ public WalletType getWalletType()
return wallet.type;
}

@Override
public GasService getGasService()
{
return viewModel.getGasService();
}

@Override
public void onSignTransaction(Web3Transaction transaction, String url)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,12 @@ public BigInteger getTokenId()
return tokenId;
}

@Override
public GasService getGasService()
{
return viewModel.getGasService();
}

private void calculateEstimateDialog()
{
if (alertDialog != null && alertDialog.isShowing()) alertDialog.dismiss();
Expand Down
7 changes: 7 additions & 0 deletions app/src/main/java/com/alphawallet/app/ui/HomeActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
import com.alphawallet.app.entity.tokens.TokenCardMeta;
import com.alphawallet.app.router.ImportTokenRouter;
import com.alphawallet.app.service.DeepLinkService;
import com.alphawallet.app.service.GasService;
import com.alphawallet.app.service.PriceAlertsService;
import com.alphawallet.app.ui.widget.entity.ActionSheetCallback;
import com.alphawallet.app.ui.widget.entity.PagerCallback;
Expand Down Expand Up @@ -667,6 +668,12 @@ public void onDestroy()
}
}

@Override
public GasService getGasService()
{
return viewModel.getGasService();
}

private void showPage(WalletPage page)
{
WalletPage oldPage = WalletPage.values()[viewPager.getCurrentItem()];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,12 @@ public WalletType getWalletType()
return viewModel.getWallet().type;
}

@Override
public GasService getGasService()
{
return viewModel.getGasService();
}

@Override
public void completeFunctionSetup()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,10 @@
import com.alphawallet.hardware.SignatureFromKey;
import com.alphawallet.token.entity.SalesOrderMalformed;
import com.alphawallet.token.tools.Convert;
import org.web3j.utils.Numeric;
import com.alphawallet.token.tools.ParseMagicLink;

import org.web3j.utils.Numeric;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.SocketTimeoutException;
Expand Down Expand Up @@ -673,6 +674,12 @@ public WalletType getWalletType()
return wallet.type;
}

@Override
public GasService getGasService()
{
return viewModel.getGasService();
}

private void txWritten(TransactionReturn txData)
{
confirmationDialog.transactionWritten(txData.hash);
Expand Down
Loading
Loading