Skip to content

Commit

Permalink
Rework gas fetch methods
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesSmartCell committed Feb 18, 2024
1 parent 1eec3f4 commit 3cfec2c
Show file tree
Hide file tree
Showing 41 changed files with 323 additions and 65 deletions.
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
9 changes: 8 additions & 1 deletion app/src/main/java/com/alphawallet/app/ui/SendActivity.java
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

0 comments on commit 3cfec2c

Please sign in to comment.