Skip to content

Commit

Permalink
Add retry client that handles SolanaJsonRpcClientError
Browse files Browse the repository at this point in the history
  • Loading branch information
ml-james committed Oct 31, 2024
1 parent b10c07e commit de1fc45
Show file tree
Hide file tree
Showing 23 changed files with 297 additions and 259 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.lmax.solana4j.client.jsonrpc;

import com.lmax.solana4j.assertion.Condition;
import com.lmax.solana4j.assertion.Waiter;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

Expand All @@ -11,7 +9,7 @@
class GetAccountInfoContractTest extends SolanaClientIntegrationTestBase
{
@Test
void shouldGetAccountInfo()
void shouldGetAccountInfo() throws SolanaJsonRpcClientException
{
// {
// "jsonrpc" : "2.0",
Expand All @@ -32,7 +30,7 @@ void shouldGetAccountInfo()
// "id" : 4
// }

final var accountInfo = Waiter.waitFor(Condition.isNotNull(() -> api.getAccountInfo(payerAccount).getResponse()));
final var accountInfo = api.getAccountInfo(payerAccount).getResponse();

assertThat(accountInfo.getOwner()).isEqualTo("11111111111111111111111111111111");
assertThat(accountInfo.getData().get(0)).isEqualTo("");
Expand All @@ -45,7 +43,7 @@ void shouldGetAccountInfo()

@Test
@Disabled
void shouldGetTokenAccountInfo()
void shouldGetTokenAccountInfo() throws SolanaJsonRpcClientException
{
// {
// "jsonrpc" : "2.0",
Expand All @@ -66,7 +64,7 @@ void shouldGetTokenAccountInfo()
// "id" : 4
// }

final var tokenAccountInfo = Waiter.waitFor(Condition.isNotNull(() -> api.getAccountInfo(tokenAccount)));
final var tokenAccountInfo = api.getAccountInfo(tokenAccount).getResponse();


// assertThat(tokenAccountInfo.getOwner()).isEqualTo("11111111111111111111111111111111");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
class GetBalanceContractTest extends SolanaClientIntegrationTestBase
{
@Test
void shouldGetBalance()
void shouldGetBalance() throws SolanaJsonRpcClientException
{
// {
// "jsonrpc" : "2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
class GetBlockHeightContractTest extends SolanaClientIntegrationTestBase
{
@Test
void shouldGetBlockHeight()
void shouldGetBlockHeight() throws SolanaJsonRpcClientException
{
// {
// "jsonrpc" : "2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
class GetLatestBlockhashContractTest extends SolanaClientIntegrationTestBase
{
@Test
void shouldGetLatestBlockhash()
void shouldGetLatestBlockhash() throws SolanaJsonRpcClientException
{
// {
// "jsonrpc" : "2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
class GetMinimumBalanceForRentExemptionContractTest extends SolanaClientIntegrationTestBase
{
@Test
void shouldGetMinimumBalanceForRentExemption()
void shouldGetMinimumBalanceForRentExemption() throws SolanaJsonRpcClientException
{
// {
// "jsonrpc" : "2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
class GetSlotContractTest extends SolanaClientIntegrationTestBase
{
@Test
void shouldGetSlot()
void shouldGetSlot() throws SolanaJsonRpcClientException
{
// {
// "jsonrpc" : "2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
class GetTokenAccountBalanceContractTest extends SolanaClientIntegrationTestBase
{
@Test
void shouldGetTokenAccountBalance()
void shouldGetTokenAccountBalance() throws SolanaJsonRpcClientException
{
// {
// "jsonrpc" : "2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class GetTransactionContractTest extends SolanaClientIntegrationTestBase
{
@Test
@Disabled
void shouldGetTransaction()
void shouldGetTransaction() throws SolanaJsonRpcClientException
{
{
// "jsonrpc" : "2.0",
Expand Down Expand Up @@ -64,7 +64,18 @@ void shouldGetTransaction()

final String transactionSignature = api.requestAirdrop(payerAccount, Sol.lamports(BigDecimal.ONE)).getResponse();

final var transaction = Waiter.waitFor(Condition.isNotNull(() -> api.getTransaction(transactionSignature)));
// will need to wait a bit for the transaction above to appear
final var transaction = Waiter.waitFor(Condition.isNotNull(() ->
{
try
{
return api.getTransaction(transactionSignature);
}
catch (SolanaJsonRpcClientException e)
{
throw new RuntimeException(e);
}
}));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
class RequestAirdropContractTest extends SolanaClientIntegrationTestBase
{
@Test
void shouldRequestAirdrop()
void shouldRequestAirdrop() throws SolanaJsonRpcClientException
{
// {
// "jsonrpc" : "2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class SendTransactionContractTest extends SolanaClientIntegrationTestBase
{
@Test
@Disabled
void shouldSendTransaction()
void shouldSendTransaction() throws SolanaJsonRpcClientException
{
final var transactionSignature = api.sendTransaction("blobWellFormed...Not");
fail();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ void moreSetup()
{
api = new SolanaJsonRpcClient(rpcUrl, true);

Waiter.waitFor(Condition.isTrue(() -> api.getSlot().getResponse() > 35));
Waiter.waitFor(Condition.isTrue(() ->
{
try
{
return api.getSlot().getResponse() > 35;
}
catch (SolanaJsonRpcClientException e)
{
throw new RuntimeException("Something went wrong in the test setup.", e);
}
}));
}
}
35 changes: 0 additions & 35 deletions client/src/main/java/com/lmax/solana4j/client/api/ErrorCode.java

This file was deleted.

34 changes: 23 additions & 11 deletions client/src/main/java/com/lmax/solana4j/client/api/SolanaApi.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.lmax.solana4j.client.api;

import com.lmax.solana4j.client.jsonrpc.SolanaJsonRpcClientException;

/**
* Represents the API for interacting with the Solana blockchain.
* This interface provides methods for sending transactions, querying account balances, requesting airdrops,
Expand All @@ -13,16 +15,18 @@ public interface SolanaApi
*
* @param transactionBlob the base64-encoded string representing the transaction
* @return the signature of the transaction, which is a base58-encoded string
* @throws SolanaJsonRpcClientException if there is an error with the JSON-RPC request
*/
SolanaClientResponse<String> sendTransaction(String transactionBlob);
SolanaClientResponse<String> sendTransaction(String transactionBlob) throws SolanaJsonRpcClientException;

/**
* Retrieves the transaction response for a given transaction signature.
*
* @param transactionSignature the base58-encoded signature of the transaction
* @return the {@link TransactionResponse} containing details of the transaction
* @throws SolanaJsonRpcClientException if there is an error with the JSON-RPC request
*/
SolanaClientResponse<TransactionResponse> getTransaction(String transactionSignature);
SolanaClientResponse<TransactionResponse> getTransaction(String transactionSignature) throws SolanaJsonRpcClientException;

/**
* Requests an airdrop of lamports to the specified address.
Expand All @@ -31,64 +35,72 @@ public interface SolanaApi
* @param address the base58-encoded public key of the recipient account
* @param amountLamports the amount of lamports to be airdropped
* @return the transaction signature as a base58-encoded string
* @throws SolanaJsonRpcClientException if there is an error with the JSON-RPC request
*/
SolanaClientResponse<String> requestAirdrop(String address, long amountLamports);
SolanaClientResponse<String> requestAirdrop(String address, long amountLamports) throws SolanaJsonRpcClientException;

/**
* Retrieves the balance of an account in lamports.
*
* @param address the base58-encoded public key of the account
* @return the balance of the account in lamports
* @throws SolanaJsonRpcClientException if there is an error with the JSON-RPC request
*/
SolanaClientResponse<Long> getBalance(String address);
SolanaClientResponse<Long> getBalance(String address) throws SolanaJsonRpcClientException;

/**
* Retrieves the token account balance of an SPL token account.
*
* @param address the base58-encoded public key of the token account
* @return the {@link TokenAmount} representing the token balance of the account
* @throws SolanaJsonRpcClientException if there is an error with the JSON-RPC request
*/
SolanaClientResponse<TokenAmount> getTokenAccountBalance(String address);
SolanaClientResponse<TokenAmount> getTokenAccountBalance(String address) throws SolanaJsonRpcClientException;

/**
* Retrieves the account information for the specified address.
* The account information includes the balance, ownership, and data stored in the account.
*
* @param address the base58-encoded public key of the account
* @return the {@link AccountInfo} containing details of the account
* @throws SolanaJsonRpcClientException if there is an error with the JSON-RPC request
*/
SolanaClientResponse<AccountInfo> getAccountInfo(String address);
SolanaClientResponse<AccountInfo> getAccountInfo(String address) throws SolanaJsonRpcClientException;

/**
* Retrieves the current block height of the Solana blockchain.
* The block height represents the number of blocks preceding the current block.
*
* @return the current block height
* @throws SolanaJsonRpcClientException if there is an error with the JSON-RPC request
*/
SolanaClientResponse<Long> getBlockHeight();
SolanaClientResponse<Long> getBlockHeight() throws SolanaJsonRpcClientException;

/**
* Retrieves the current slot number.
* A slot is a specific point in time or block on the Solana blockchain.
*
* @return the current slot number
* @throws SolanaJsonRpcClientException if there is an error with the JSON-RPC request
*/
SolanaClientResponse<Long> getSlot();
SolanaClientResponse<Long> getSlot() throws SolanaJsonRpcClientException;

/**
* Retrieves the most recent blockhash.
* The blockhash ensures that a transaction is processed within a specific time window.
*
* @return the {@link Blockhash} representing the most recent blockhash
* @throws SolanaJsonRpcClientException if there is an error with the JSON-RPC request
*/
SolanaClientResponse<Blockhash> getLatestBlockhash();
SolanaClientResponse<Blockhash> getLatestBlockhash() throws SolanaJsonRpcClientException;

/**
* Retrieves the minimum balance required for rent exemption for an account of the given size.
* This is the minimum balance needed to ensure the account is rent-exempt.
*
* @param size the size of the account in bytes
* @return the minimum balance in lamports for rent exemption
* @throws SolanaJsonRpcClientException if there is an error with the JSON-RPC request
*/
SolanaClientResponse<Long> getMinimumBalanceForRentExemption(int size);
}
SolanaClientResponse<Long> getMinimumBalanceForRentExemption(int size) throws SolanaJsonRpcClientException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

public interface SolanaClientError
{
ErrorCode getErrorCode();
long getErrorCode();

String getErrorMessage();

boolean isRecoverable();
}
Loading

0 comments on commit de1fc45

Please sign in to comment.