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

Fix for RPC key usage #3362

Merged
merged 1 commit into from
Feb 20, 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
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public AAATokenScriptCertificateTest()
fail("Please config seed phrase and wallet address for this API level first.");
}

web3j = EthUtils.buildWeb3j(GANACHE_URL);
web3j = EthUtils.buildWeb3j(GANACHE_URL, 2L);

String privateKey = array[0];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public void setUp()
contractOwnerCredentials = Credentials.create(contractOwnerPk);

super.setUp();
web3j = EthUtils.buildWeb3j(GANACHE_URL);
web3j = EthUtils.buildWeb3j(GANACHE_URL, 2L);
deployTestTokenOnGanache();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
*/
public abstract class EthUtils
{
public static Web3j buildWeb3j(String url)
public static Web3j buildWeb3j(String url, long chainId)
{
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(C.CONNECT_TIMEOUT, TimeUnit.SECONDS)
Expand All @@ -41,7 +41,7 @@ public static Web3j buildWeb3j(String url)
.retryOnConnectionFailure(true)
.build();

AWHttpService svs = new AWHttpService(url, url, client, false);
AWHttpService svs = new AWHttpService(url, url, chainId, client,null, null, null, false);
return Web3j.build(svs);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@
import java.util.concurrent.ConcurrentHashMap;

import io.reactivex.Single;
import io.reactivex.schedulers.Schedulers;
import timber.log.Timber;

/**
Expand Down Expand Up @@ -958,7 +959,8 @@
.map(transactionResult -> addParseResultIfValid(token, useTokenId, attr, transactionResult))// only cache live transaction result
.map(result -> restoreFromDBIfRequired(result, cachedResult)) // If network unavailable restore value from cache
.map(txResult -> attrIf.storeAuxData(walletAddress, txResult)) // store new data
.map(result -> parseFunctionResult(result, attr)); // write returned data into attribute
.map(result -> parseFunctionResult(result, attr))
.subscribeOn(Schedulers.io()); // write returned data into attribute

Check warning on line 963 in app/src/main/java/com/alphawallet/app/entity/tokenscript/TokenscriptFunction.java

View check run for this annotation

Codecov / codecov/patch

app/src/main/java/com/alphawallet/app/entity/tokenscript/TokenscriptFunction.java#L962-L963

Added lines #L962 - L963 were not covered by tests
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,8 @@

private void buildWeb3jClient(NetworkInfo networkInfo)
{
AWHttpService publicNodeService = new AWHttpService(networkInfo.rpcServerUrl, networkInfo.backupNodeUrl, okClient, false);
HttpServiceHelper.addRequiredCredentials(networkInfo.chainId, publicNodeService, KeyProviderFactory.get().getKlaytnKey(),
KeyProviderFactory.get().getInfuraSecret(), EthereumNetworkBase.usesProductionKey);
AWHttpService publicNodeService = new AWHttpService(networkInfo.rpcServerUrl, networkInfo.backupNodeUrl, networkInfo.chainId, okClient, KeyProviderFactory.get().getInfuraKey(),
KeyProviderFactory.get().getInfuraSecret(), KeyProviderFactory.get().getKlaytnKey(), false);

Check warning on line 135 in app/src/main/java/com/alphawallet/app/repository/TokenRepository.java

View check run for this annotation

Codecov / codecov/patch

app/src/main/java/com/alphawallet/app/repository/TokenRepository.java#L134-L135

Added lines #L134 - L135 were not covered by tests
web3jNodeServers.put(networkInfo.chainId, Web3j.build(publicNodeService));
}

Expand Down Expand Up @@ -1317,9 +1316,8 @@
secondaryNode = EthereumNetworkRepository.getNodeURLByNetworkId(chainId);
}

AWHttpService publicNodeService = new AWHttpService(nodeUrl, secondaryNode, okClient, false);
HttpServiceHelper.addRequiredCredentials(chainId, publicNodeService, KeyProviderFactory.get().getKlaytnKey(),
KeyProviderFactory.get().getInfuraSecret(), EthereumNetworkBase.usesProductionKey);
AWHttpService publicNodeService = new AWHttpService(nodeUrl, secondaryNode, chainId, okClient, KeyProviderFactory.get().getInfuraKey(),
KeyProviderFactory.get().getInfuraSecret(), KeyProviderFactory.get().getKlaytnKey(), false);

Check warning on line 1320 in app/src/main/java/com/alphawallet/app/repository/TokenRepository.java

View check run for this annotation

Codecov / codecov/patch

app/src/main/java/com/alphawallet/app/repository/TokenRepository.java#L1319-L1320

Added lines #L1319 - L1320 were not covered by tests
return Web3j.build(publicNodeService);
}

Expand All @@ -1332,9 +1330,8 @@
.retryOnConnectionFailure(true)
.build();

AWHttpService publicNodeService = new AWHttpService(EthereumNetworkRepository.getNodeURLByNetworkId(chainId), EthereumNetworkRepository.getSecondaryNodeURL(chainId), okClient, false);
HttpServiceHelper.addRequiredCredentials(chainId, publicNodeService, KeyProviderFactory.get().getKlaytnKey(),
KeyProviderFactory.get().getInfuraSecret(), EthereumNetworkBase.usesProductionKey);
AWHttpService publicNodeService = new AWHttpService(EthereumNetworkRepository.getNodeURLByNetworkId(chainId), EthereumNetworkRepository.getSecondaryNodeURL(chainId), chainId, okClient, KeyProviderFactory.get().getInfuraKey(),
KeyProviderFactory.get().getInfuraSecret(), KeyProviderFactory.get().getKlaytnKey(), false);
return Web3j.build(publicNodeService);
}

Expand Down
60 changes: 49 additions & 11 deletions app/src/main/java/com/alphawallet/app/service/AWHttpService.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@
*
*/

import static com.alphawallet.ethereum.EthereumNetworkBase.KLAYTN_BAOBAB_ID;
import static com.alphawallet.ethereum.EthereumNetworkBase.KLAYTN_ID;
import static okhttp3.ConnectionSpec.CLEARTEXT;

import android.text.TextUtils;

import com.google.gson.JsonParseException;

import org.slf4j.Logger;
Expand Down Expand Up @@ -38,7 +42,6 @@
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import timber.log.Timber;

/** HTTP implementation of our services API. */
public class AWHttpService extends HttpService
Expand Down Expand Up @@ -101,15 +104,23 @@
private final String secondaryUrl;

private final boolean includeRawResponse;
private final String infuraSecret;
private final String infuraKey;
private final String klaytnKey;
private final long chainId;

private final HashMap<String, String> headers = new HashMap<>();

public AWHttpService(String url, String secondaryUrl, OkHttpClient httpClient, boolean includeRawResponses) {
public AWHttpService(String url, String secondaryUrl, long chainId, OkHttpClient httpClient, String infuraKey, String infuraSecret, String klaytnKey, boolean includeRawResponses) {
super(includeRawResponses);
this.url = url;
this.httpClient = httpClient;
this.includeRawResponse = includeRawResponses;
this.secondaryUrl = secondaryUrl;
this.infuraKey = infuraKey;
this.infuraSecret = infuraSecret;
this.klaytnKey = klaytnKey;
this.chainId = chainId;
}

@Override
Expand All @@ -125,6 +136,8 @@
requestBody = RequestBody.create("", MEDIA_TYPE_TEXT);
}

addRequiredSecrets(url);

okhttp3.Request httpRequest =
new okhttp3.Request.Builder()
.url(url)
Expand All @@ -138,20 +151,31 @@
//try primary node
response = httpClient.newCall(httpRequest).execute();
}
catch (SocketTimeoutException e) //seamlessly attempt a call to secondary node if primary timed out
catch (SocketTimeoutException e)

Check warning on line 154 in app/src/main/java/com/alphawallet/app/service/AWHttpService.java

View check run for this annotation

Codecov / codecov/patch

app/src/main/java/com/alphawallet/app/service/AWHttpService.java#L154

Added line #L154 was not covered by tests
{
if (secondaryUrl != null) //only if we have a secondary node
{
return trySecondaryNode(request);

Check warning on line 158 in app/src/main/java/com/alphawallet/app/service/AWHttpService.java

View check run for this annotation

Codecov / codecov/patch

app/src/main/java/com/alphawallet/app/service/AWHttpService.java#L158

Added line #L158 was not covered by tests
}
}
catch (java.io.InterruptedIOException e) //interrupted exception should be thrown back

Check warning on line 161 in app/src/main/java/com/alphawallet/app/service/AWHttpService.java

View check run for this annotation

Codecov / codecov/patch

app/src/main/java/com/alphawallet/app/service/AWHttpService.java#L161

Added line #L161 was not covered by tests
{
throw e;

Check warning on line 163 in app/src/main/java/com/alphawallet/app/service/AWHttpService.java

View check run for this annotation

Codecov / codecov/patch

app/src/main/java/com/alphawallet/app/service/AWHttpService.java#L163

Added line #L163 was not covered by tests
}
catch (Exception e) //seamlessly attempt a call to secondary node if primary node has some error

Check warning on line 165 in app/src/main/java/com/alphawallet/app/service/AWHttpService.java

View check run for this annotation

Codecov / codecov/patch

app/src/main/java/com/alphawallet/app/service/AWHttpService.java#L165

Added line #L165 was not covered by tests
{
if (secondaryUrl != null) //only if we have a secondary node
{
return trySecondaryNode(request);
}
else
{
throw new SocketTimeoutException();
throw e; //throw the error back up the stack

Check warning on line 173 in app/src/main/java/com/alphawallet/app/service/AWHttpService.java

View check run for this annotation

Codecov / codecov/patch

app/src/main/java/com/alphawallet/app/service/AWHttpService.java#L173

Added line #L173 was not covered by tests
}
}
//TODO: Also check java.io.InterruptedIOException

if (response.code() / 100 == 4) //rate limited
if (response.code() / 100 != 2)
{
response.close();
return trySecondaryNode(request);
Expand All @@ -162,16 +186,17 @@

private InputStream trySecondaryNode(String request) throws IOException
{
Timber.d("trySecondaryNode: ");
RequestBody requestBody = RequestBody.create(request, JSON_MEDIA_TYPE);

okhttp3.Request httpRequest =
new okhttp3.Request.Builder().url(secondaryUrl).post(requestBody).build();

okhttp3.Response response;
addRequiredSecrets(secondaryUrl);

response = httpClient.newCall(httpRequest).execute();
okhttp3.Request httpRequest =
new okhttp3.Request.Builder()
.url(secondaryUrl)
.headers(buildHeaders())
.post(requestBody).build();

okhttp3.Response response = httpClient.newCall(httpRequest).execute();
return processNodeResponse(response, request, true);
}

Expand Down Expand Up @@ -244,6 +269,19 @@
}
}

private void addRequiredSecrets(String url)
{
if (!TextUtils.isEmpty(infuraKey) && url.endsWith(infuraKey) && !TextUtils.isEmpty(infuraSecret)) //primary InfuraKey has secret
{
addHeader("Authorization", "Basic " + infuraSecret);
}
else if (!TextUtils.isEmpty(klaytnKey) && (chainId == KLAYTN_BAOBAB_ID || chainId == KLAYTN_ID))
{
addHeader("x-chain-id", Long.toString(chainId));
addHeader("Authorization", "Basic " + klaytnKey);

Check warning on line 281 in app/src/main/java/com/alphawallet/app/service/AWHttpService.java

View check run for this annotation

Codecov / codecov/patch

app/src/main/java/com/alphawallet/app/service/AWHttpService.java#L280-L281

Added lines #L280 - L281 were not covered by tests
}
}

private Headers buildHeaders() {
return Headers.of(headers);
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/test/java/com/alphawallet/app/ENSTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public static AWHttpService getWeb3jService()
.writeTimeout(C.LONG_WRITE_TIMEOUT, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.build();
return new AWHttpService("https://mainnet.infura.io/v3/" + TextUtils.rot(Inf), "https://rpc.ankr.com/eth", okClient, false);
return new AWHttpService("https://mainnet.infura.io/v3/" + TextUtils.rot(Inf), "https://rpc.ankr.com/eth", 1, okClient, null, null, null, false);
}

public static Web3j getWeb3j(AWHttpService service)
Expand Down
Loading