From 577aa98196e6bd84e3b9c87e3d1a50325e4b9cd6 Mon Sep 17 00:00:00 2001 From: jeffyanta Date: Wed, 21 Oct 2026 15:33:11 -0400 Subject: [PATCH 1/3] Solana client only uses finalized commitment level --- ocp/balance/calculator.go | 2 +- ocp/common/account.go | 2 +- ocp/common/subsidizer.go | 3 +- ocp/currency/reserve.go | 3 +- ocp/data/blockchain.go | 38 ++++----- ocp/data/transaction/transaction.go | 2 +- ocp/rpc/transaction/intent_handler.go | 2 +- ocp/rpc/transaction/intent_test.go | 2 +- ocp/rpc/transaction/stateful_swap.go | 2 +- ocp/rpc/transaction/withdraw.go | 4 +- ocp/transaction/coinbase_swap.go | 3 +- ocp/transaction/submit.go | 2 +- ocp/worker/currency/feeburner/worker.go | 2 +- ocp/worker/currency/launcher/util.go | 38 ++++----- ocp/worker/geyser/external_deposit.go | 15 ++-- ocp/worker/geyser/metrics.go | 3 +- ocp/worker/geyser/retry.go | 6 -- ocp/worker/nonce/pool.go | 6 +- ocp/worker/nonce/util.go | 6 +- ocp/worker/sequencer/fulfillment_handler.go | 2 +- ocp/worker/sequencer/utils.go | 4 +- ocp/worker/swap/util.go | 4 +- ocp/worker/swap/worker.go | 8 +- solana/client.go | 87 +++++++++------------ solana/client_test.go | 9 +-- solana/client_with_fallback.go | 36 ++++----- solana/client_with_fallback_test.go | 54 ++++++------- solana/token/client.go | 4 +- 28 files changed, 160 insertions(+), 189 deletions(-) diff --git a/ocp/balance/calculator.go b/ocp/balance/calculator.go index 61c8acc..89feba0 100644 --- a/ocp/balance/calculator.go +++ b/ocp/balance/calculator.go @@ -92,7 +92,7 @@ func CalculateFromBlockchain(ctx context.Context, data ocp_data.Provider, tokenA } // todo: we may need something that's more resistant to RPC nodes with stale account state - quarks, slot, err := data.GetBlockchainBalance(ctx, tokenAccount.PublicKey().ToBase58(), solana.CommitmentConfirmed) + quarks, slot, err := data.GetBlockchainBalance(ctx, tokenAccount.PublicKey().ToBase58()) if err == solana.ErrNoBalance { // We can't tell whether // 1. RPC node is behind, and observed a state before the account existed diff --git a/ocp/common/account.go b/ocp/common/account.go index 406c637..41eea9e 100644 --- a/ocp/common/account.go +++ b/ocp/common/account.go @@ -570,7 +570,7 @@ func (a *TimelockAccounts) GetInitializeInstruction(vmAuthority, memory *Account // ValidateExternalTokenAccount validates an address is an external token account for the provided mint func ValidateExternalTokenAccount(ctx context.Context, data ocp_data.Provider, tokenAccount, mintAccount *Account) (bool, string, error) { - _, err := data.GetBlockchainTokenAccountInfo(ctx, tokenAccount.PublicKey().ToBase58(), mintAccount.PublicKey().ToBase58(), solana.CommitmentFinalized) + _, err := data.GetBlockchainTokenAccountInfo(ctx, tokenAccount.PublicKey().ToBase58(), mintAccount.PublicKey().ToBase58()) switch err { case nil: // Double check there were no race conditions between other SubmitIntent diff --git a/ocp/common/subsidizer.go b/ocp/common/subsidizer.go index be3d3b7..e985cbb 100644 --- a/ocp/common/subsidizer.go +++ b/ocp/common/subsidizer.go @@ -9,7 +9,6 @@ import ( ocp_data "github.com/code-payments/ocp-server/ocp/data" "github.com/code-payments/ocp-server/ocp/data/fulfillment" "github.com/code-payments/ocp-server/ocp/data/nonce" - "github.com/code-payments/ocp-server/solana" ) // todo: always assumes mainnet @@ -112,7 +111,7 @@ func InjectTestSubsidizer(ctx context.Context, data ocp_data.Provider, testAccou // GetCurrentSubsidizerBalance returns the subsidizer's current balance in lamports. func GetCurrentSubsidizerBalance(ctx context.Context, data ocp_data.Provider) (uint64, error) { - accountInfo, _, err := data.GetBlockchainAccountInfo(ctx, GetSubsidizer().PublicKey().ToBase58(), solana.CommitmentProcessed) + accountInfo, _, err := data.GetBlockchainAccountInfo(ctx, GetSubsidizer().PublicKey().ToBase58()) if err != nil { return 0, err } diff --git a/ocp/currency/reserve.go b/ocp/currency/reserve.go index d59e3a9..482ba9a 100644 --- a/ocp/currency/reserve.go +++ b/ocp/currency/reserve.go @@ -7,7 +7,6 @@ import ( "github.com/code-payments/ocp-server/ocp/common" ocp_data "github.com/code-payments/ocp-server/ocp/data" - "github.com/code-payments/ocp-server/solana" "github.com/code-payments/ocp-server/solana/currencycreator" "github.com/code-payments/ocp-server/solana/token" ) @@ -25,7 +24,7 @@ func GetLaunchpadCurrencyCirculatingSupply(ctx context.Context, data ocp_data.Pr return 0, 0, time.Time{}, err } - ai, slot, err := data.GetBlockchainAccountInfo(ctx, accounts.VaultMint.PublicKey().ToBase58(), solana.CommitmentFinalized) + ai, slot, err := data.GetBlockchainAccountInfo(ctx, accounts.VaultMint.PublicKey().ToBase58()) if err != nil { return 0, 0, time.Time{}, err } diff --git a/ocp/data/blockchain.go b/ocp/data/blockchain.go index d361edc..10e1d86 100644 --- a/ocp/data/blockchain.go +++ b/ocp/data/blockchain.go @@ -18,17 +18,17 @@ const ( type BlockchainData interface { SubmitBlockchainTransaction(ctx context.Context, tx *solana.Transaction) (solana.Signature, error) - GetBlockchainAccountInfo(ctx context.Context, account string, commitment solana.Commitment) (*solana.AccountInfo, uint64, error) + GetBlockchainAccountInfo(ctx context.Context, account string) (*solana.AccountInfo, uint64, error) GetBlockchainAccountDataAfterBlock(ctx context.Context, account string, slot uint64) ([]byte, uint64, error) - GetBlockchainBalance(ctx context.Context, account string, commitment solana.Commitment) (uint64, uint64, error) + GetBlockchainBalance(ctx context.Context, account string) (uint64, uint64, error) GetBlockchainBlock(ctx context.Context, slot uint64) (*solana.Block, error) - GetBlockchainHistory(ctx context.Context, account string, commitment solana.Commitment, opts ...query.Option) ([]*solana.TransactionSignature, error) + GetBlockchainHistory(ctx context.Context, account string, opts ...query.Option) ([]*solana.TransactionSignature, error) GetBlockchainMinimumBalanceForRentExemption(ctx context.Context, size uint64) (uint64, error) GetBlockchainLatestBlockhash(ctx context.Context) (solana.Blockhash, error) GetBlockchainSignatureStatuses(ctx context.Context, signatures []solana.Signature) ([]*solana.SignatureStatus, error) - GetBlockchainSlot(ctx context.Context, commitment solana.Commitment) (uint64, error) - GetBlockchainTokenAccountInfo(ctx context.Context, account, mint string, commitment solana.Commitment) (*token.Account, error) - GetBlockchainTransaction(ctx context.Context, sig string, commitment solana.Commitment) (*solana.ConfirmedTransaction, error) + GetBlockchainSlot(ctx context.Context) (uint64, error) + GetBlockchainTokenAccountInfo(ctx context.Context, account, mint string) (*token.Account, error) + GetBlockchainTransaction(ctx context.Context, sig string) (*solana.TransactionWithMeta, error) GetBlockchainTransactionTokenBalances(ctx context.Context, sig string) (*solana.TransactionTokenBalances, error) GetBlockchainFilteredProgramAccounts(ctx context.Context, program string, offset uint, filterValue []byte) ([]solana.ProgramAccount, uint64, error) } @@ -65,7 +65,7 @@ func (dp *BlockchainProvider) SubmitBlockchainTransaction(ctx context.Context, t tracer := metrics.TraceMethodCall(ctx, blockchainProviderMetricsName, "SubmitBlockchainTransaction") defer tracer.End() - res, err := dp.sc.SubmitTransaction(*tx, solana.CommitmentProcessed) + res, err := dp.sc.SubmitTransaction(*tx) if err != nil { tracer.OnError(err) @@ -74,7 +74,7 @@ func (dp *BlockchainProvider) SubmitBlockchainTransaction(ctx context.Context, t return res, err } -func (dp *BlockchainProvider) GetBlockchainAccountInfo(ctx context.Context, account string, commitment solana.Commitment) (*solana.AccountInfo, uint64, error) { +func (dp *BlockchainProvider) GetBlockchainAccountInfo(ctx context.Context, account string) (*solana.AccountInfo, uint64, error) { tracer := metrics.TraceMethodCall(ctx, blockchainProviderMetricsName, "GetBlockchainAccountInfo") defer tracer.End() @@ -82,7 +82,7 @@ func (dp *BlockchainProvider) GetBlockchainAccountInfo(ctx context.Context, acco if err != nil { return nil, 0, err } - accountInfo, slot, err := dp.sc.GetAccountInfo(accountId, commitment) + accountInfo, slot, err := dp.sc.GetAccountInfo(accountId) if err != nil { tracer.OnError(err) } @@ -104,7 +104,7 @@ func (dp *BlockchainProvider) GetBlockchainAccountDataAfterBlock(ctx context.Con } return data, block, err } -func (dp *BlockchainProvider) GetBlockchainTokenAccountInfo(ctx context.Context, account, mint string, commitment solana.Commitment) (*token.Account, error) { +func (dp *BlockchainProvider) GetBlockchainTokenAccountInfo(ctx context.Context, account, mint string) (*token.Account, error) { tracer := metrics.TraceMethodCall(ctx, blockchainProviderMetricsName, "GetBlockchainTokenAccountInfo") defer tracer.End() @@ -118,18 +118,18 @@ func (dp *BlockchainProvider) GetBlockchainTokenAccountInfo(ctx context.Context, return nil, err } - res, err := dp.tc.GetAccount(accountId, mintId, commitment) + res, err := dp.tc.GetAccount(accountId, mintId) if err != nil { tracer.OnError(err) } return res, err } -func (dp *BlockchainProvider) GetBlockchainSlot(ctx context.Context, commitment solana.Commitment) (uint64, error) { +func (dp *BlockchainProvider) GetBlockchainSlot(ctx context.Context) (uint64, error) { tracer := metrics.TraceMethodCall(ctx, blockchainProviderMetricsName, "GetBlockchainSlot") defer tracer.End() - res, err := dp.sc.GetSlot(commitment) + res, err := dp.sc.GetSlot() if err != nil { tracer.OnError(err) @@ -149,7 +149,7 @@ func (dp *BlockchainProvider) GetBlockchainBlock(ctx context.Context, slot uint6 return res, err } -func (dp *BlockchainProvider) GetBlockchainHistory(ctx context.Context, account string, commitment solana.Commitment, opts ...query.Option) ([]*solana.TransactionSignature, error) { +func (dp *BlockchainProvider) GetBlockchainHistory(ctx context.Context, account string, opts ...query.Option) ([]*solana.TransactionSignature, error) { tracer := metrics.TraceMethodCall(ctx, blockchainProviderMetricsName, "GetBlockchainHistory") defer tracer.End() @@ -169,7 +169,7 @@ func (dp *BlockchainProvider) GetBlockchainHistory(ctx context.Context, account return nil, err } - res, err := dp.sc.GetSignaturesForAddress(publicKey, commitment, req.Limit, cursor, "") + res, err := dp.sc.GetSignaturesForAddress(publicKey, req.Limit, cursor, "") if err != nil { tracer.OnError(err) @@ -177,7 +177,7 @@ func (dp *BlockchainProvider) GetBlockchainHistory(ctx context.Context, account return res, err } -func (dp *BlockchainProvider) GetBlockchainTransaction(ctx context.Context, sig string, commitment solana.Commitment) (*solana.ConfirmedTransaction, error) { +func (dp *BlockchainProvider) GetBlockchainTransaction(ctx context.Context, sig string) (*solana.TransactionWithMeta, error) { tracer := metrics.TraceMethodCall(ctx, blockchainProviderMetricsName, "GetBlockchainTransaction") defer tracer.End() @@ -189,7 +189,7 @@ func (dp *BlockchainProvider) GetBlockchainTransaction(ctx context.Context, sig var signature solana.Signature copy(signature[:], raw) - res, err := dp.sc.GetTransaction(signature, commitment) + res, err := dp.sc.GetTransaction(signature) if err != nil { tracer.OnError(err) return nil, err @@ -234,7 +234,7 @@ func (dp *BlockchainProvider) GetBlockchainMinimumBalanceForRentExemption(ctx co return res, err } -func (dp *BlockchainProvider) GetBlockchainBalance(ctx context.Context, account string, commitment solana.Commitment) (uint64, uint64, error) { +func (dp *BlockchainProvider) GetBlockchainBalance(ctx context.Context, account string) (uint64, uint64, error) { tracer := metrics.TraceMethodCall(ctx, blockchainProviderMetricsName, "GetBlockchainBalance") defer tracer.End() @@ -243,7 +243,7 @@ func (dp *BlockchainProvider) GetBlockchainBalance(ctx context.Context, account return 0, 0, err } - quarks, slot, err := dp.sc.GetTokenAccountBalance(accountId, commitment) + quarks, slot, err := dp.sc.GetTokenAccountBalance(accountId) if err != nil { tracer.OnError(err) diff --git a/ocp/data/transaction/transaction.go b/ocp/data/transaction/transaction.go index 7880276..d06863b 100644 --- a/ocp/data/transaction/transaction.go +++ b/ocp/data/transaction/transaction.go @@ -87,7 +87,7 @@ func (r *Record) Unmarshal() (*solana.Transaction, error) { return &tx, nil } -func FromConfirmedTransaction(tx *solana.ConfirmedTransaction) (*Record, error) { +func FromTransactionWithMeta(tx *solana.TransactionWithMeta) (*Record, error) { if tx.Transaction.Message.Version != solana.MessageVersionLegacy { return nil, errors.New("unsupported transaction version") } diff --git a/ocp/rpc/transaction/intent_handler.go b/ocp/rpc/transaction/intent_handler.go index 022e8f0..7febb9f 100644 --- a/ocp/rpc/transaction/intent_handler.go +++ b/ocp/rpc/transaction/intent_handler.go @@ -2862,7 +2862,7 @@ func validateTimelockUnlockStateDoesntExist(ctx context.Context, data ocp_data.P return err } - _, _, err = data.GetBlockchainAccountInfo(ctx, timelockAccounts.Unlock.PublicKey().ToBase58(), solana.CommitmentFinalized) + _, _, err = data.GetBlockchainAccountInfo(ctx, timelockAccounts.Unlock.PublicKey().ToBase58()) switch err { case nil: return NewIntentDeniedError("an account being opened has already initiated an unlock") diff --git a/ocp/rpc/transaction/intent_test.go b/ocp/rpc/transaction/intent_test.go index 2a56010..1a7db9f 100644 --- a/ocp/rpc/transaction/intent_test.go +++ b/ocp/rpc/transaction/intent_test.go @@ -217,7 +217,7 @@ func newTestDataProvider() *testDataProvider { } } -func (p *testDataProvider) GetBlockchainAccountInfo(ctx context.Context, account string, commitment solana.Commitment) (*solana.AccountInfo, uint64, error) { +func (p *testDataProvider) GetBlockchainAccountInfo(ctx context.Context, account string) (*solana.AccountInfo, uint64, error) { p.mu.Lock() defer p.mu.Unlock() diff --git a/ocp/rpc/transaction/stateful_swap.go b/ocp/rpc/transaction/stateful_swap.go index a24e57e..d19189b 100644 --- a/ocp/rpc/transaction/stateful_swap.go +++ b/ocp/rpc/transaction/stateful_swap.go @@ -934,7 +934,7 @@ func (s *transactionServer) handleStablecoinStatefulSwap( return handleStatefulSwapError(streamer, NewSwapValidationError("owner cannot be swap authority")) } - destinationOwnerAccountInfo, _, err := s.data.GetBlockchainAccountInfo(ctx, destinationOwner.PublicKey().ToBase58(), solana.CommitmentFinalized) + destinationOwnerAccountInfo, _, err := s.data.GetBlockchainAccountInfo(ctx, destinationOwner.PublicKey().ToBase58()) switch err { case nil: if bytes.Equal(destinationOwnerAccountInfo.Owner, token.ProgramKey) { diff --git a/ocp/rpc/transaction/withdraw.go b/ocp/rpc/transaction/withdraw.go index f3521ab..0bb1edd 100644 --- a/ocp/rpc/transaction/withdraw.go +++ b/ocp/rpc/transaction/withdraw.go @@ -71,7 +71,7 @@ func (s *transactionServer) CanWithdrawToAccount(ctx context.Context, req *trans // if !isOnCurve { - _, err = s.data.GetBlockchainTokenAccountInfo(ctx, accountToCheck.PublicKey().ToBase58(), mintAccount.PublicKey().ToBase58(), solana.CommitmentFinalized) + _, err = s.data.GetBlockchainTokenAccountInfo(ctx, accountToCheck.PublicKey().ToBase58(), mintAccount.PublicKey().ToBase58()) switch err { case nil: return &transactionpb.CanWithdrawToAccountResponse{ @@ -144,7 +144,7 @@ func (s *transactionServer) CanWithdrawToAccount(ctx context.Context, req *trans return nil, status.Error(codes.Internal, "") } - _, err = s.data.GetBlockchainTokenAccountInfo(ctx, ata.PublicKey().ToBase58(), mintAccount.PublicKey().ToBase58(), solana.CommitmentFinalized) + _, err = s.data.GetBlockchainTokenAccountInfo(ctx, ata.PublicKey().ToBase58(), mintAccount.PublicKey().ToBase58()) switch err { case nil: return &transactionpb.CanWithdrawToAccountResponse{ diff --git a/ocp/transaction/coinbase_swap.go b/ocp/transaction/coinbase_swap.go index 8a237f2..f68a73e 100644 --- a/ocp/transaction/coinbase_swap.go +++ b/ocp/transaction/coinbase_swap.go @@ -70,7 +70,7 @@ func GetCoinbaseSwapAccounts(ctx context.Context, data ocp_data.Provider, fromMi return nil, errors.Wrap(err, "error getting whitelist address") } - poolAccountInfo, _, err := data.GetBlockchainAccountInfo(ctx, base58.Encode(pool), solana.CommitmentProcessed) + poolAccountInfo, _, err := data.GetBlockchainAccountInfo(ctx, base58.Encode(pool)) if err != nil { return nil, errors.Wrap(err, "error getting coinbase liquidity pool account info") } @@ -125,7 +125,6 @@ func GetCoinbaseSwapDestinationLiquidity(ctx context.Context, data ocp_data.Prov ctx, base58.Encode(outVaultTokenAccount), base58.Encode(toMint), - solana.CommitmentProcessed, ) if err != nil { return 0, errors.Wrap(err, "error getting out vault token account info") diff --git a/ocp/transaction/submit.go b/ocp/transaction/submit.go index 3be4b85..3df2aa5 100644 --- a/ocp/transaction/submit.go +++ b/ocp/transaction/submit.go @@ -30,7 +30,7 @@ func SubmitAndWaitForFinalization(ctx context.Context, data ocp_data.BlockchainD _, err = retry.Retry( func() error { - finalizedTxn, err := data.GetBlockchainTransaction(ctx, sig, solana.CommitmentFinalized) + finalizedTxn, err := data.GetBlockchainTransaction(ctx, sig) if err == solana.ErrSignatureNotFound { return err } diff --git a/ocp/worker/currency/feeburner/worker.go b/ocp/worker/currency/feeburner/worker.go index 092bb14..e770e9a 100644 --- a/ocp/worker/currency/feeburner/worker.go +++ b/ocp/worker/currency/feeburner/worker.go @@ -120,7 +120,7 @@ func (p *runtime) makeBurnTarget(record *currency.MetadataRecord) (*burnTarget, } func (p *runtime) hasFeesToBurn(ctx context.Context, record *currency.MetadataRecord) (bool, error) { - ai, _, err := p.data.GetBlockchainAccountInfo(ctx, record.LiquidityPool, solana.CommitmentFinalized) + ai, _, err := p.data.GetBlockchainAccountInfo(ctx, record.LiquidityPool) if err == solana.ErrNoAccountInfo { return false, nil } else if err != nil { diff --git a/ocp/worker/currency/launcher/util.go b/ocp/worker/currency/launcher/util.go index 5304cf1..17367d3 100644 --- a/ocp/worker/currency/launcher/util.go +++ b/ocp/worker/currency/launcher/util.go @@ -188,7 +188,7 @@ func validateAuthorityPrivateKeyExists(ctx context.Context, data ocp_data.Provid } func validateMinimumAuthorityFunding(ctx context.Context, data ocp_data.Provider, account *common.Account, amount uint64) (bool, uint64, error) { - ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58(), solana.CommitmentFinalized) + ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58()) switch err { case nil: if ai.Lamports >= amount { @@ -203,7 +203,7 @@ func validateMinimumAuthorityFunding(ctx context.Context, data ocp_data.Provider } func returnAuthorityFundsToSubsidizer(ctx context.Context, data ocp_data.Provider, subsidizer, authority *common.Account) error { - ai, _, err := data.GetBlockchainAccountInfo(ctx, authority.PublicKey().ToBase58(), solana.CommitmentFinalized) + ai, _, err := data.GetBlockchainAccountInfo(ctx, authority.PublicKey().ToBase58()) if err == solana.ErrNoAccountInfo { return nil } else if err != nil { @@ -251,7 +251,7 @@ func fundAuthority(ctx context.Context, data ocp_data.Provider, subsidizer, acco } func validateMintExists(ctx context.Context, data ocp_data.Provider, account *common.Account) (bool, error) { - ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58(), solana.CommitmentFinalized) + ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58()) if err == solana.ErrNoAccountInfo { return false, nil } else if err != nil { @@ -268,7 +268,7 @@ func validateMintExists(ctx context.Context, data ocp_data.Provider, account *co } func validateCurrencyConfigExists(ctx context.Context, data ocp_data.Provider, account *common.Account) (bool, error) { - ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58(), solana.CommitmentFinalized) + ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58()) if err == solana.ErrNoAccountInfo { return false, nil } else if err != nil { @@ -285,7 +285,7 @@ func validateCurrencyConfigExists(ctx context.Context, data ocp_data.Provider, a } func validateLiquidityPoolExists(ctx context.Context, data ocp_data.Provider, account *common.Account) (bool, error) { - ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58(), solana.CommitmentFinalized) + ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58()) if err == solana.ErrNoAccountInfo { return false, nil } else if err != nil { @@ -302,7 +302,7 @@ func validateLiquidityPoolExists(ctx context.Context, data ocp_data.Provider, ac } func validateVmExists(ctx context.Context, data ocp_data.Provider, account *common.Account) (bool, error) { - ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58(), solana.CommitmentFinalized) + ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58()) if err == solana.ErrNoAccountInfo { return false, nil } else if err != nil { @@ -319,7 +319,7 @@ func validateVmExists(ctx context.Context, data ocp_data.Provider, account *comm } func validateAltExists(ctx context.Context, data ocp_data.Provider, account *common.Account) (bool, error) { - ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58(), solana.CommitmentFinalized) + ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58()) if err == solana.ErrNoAccountInfo { return false, nil } else if err != nil { @@ -336,7 +336,7 @@ func validateAltExists(ctx context.Context, data ocp_data.Provider, account *com } func validateAltIsExtended(ctx context.Context, data ocp_data.Provider, account *common.Account) (bool, error) { - ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58(), solana.CommitmentFinalized) + ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58()) if err == solana.ErrNoAccountInfo { return false, nil } else if err != nil { @@ -354,7 +354,7 @@ func validateAltIsExtended(ctx context.Context, data ocp_data.Provider, account } func validateFeeAccountExists(ctx context.Context, data ocp_data.Provider, account *common.Account) (bool, error) { - ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58(), solana.CommitmentFinalized) + ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58()) if err == solana.ErrNoAccountInfo { return false, nil } else if err != nil { @@ -371,7 +371,7 @@ func validateFeeAccountExists(ctx context.Context, data ocp_data.Provider, accou } func validateMemoryAccountExists(ctx context.Context, data ocp_data.Provider, account *common.Account) (bool, error) { - ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58(), solana.CommitmentFinalized) + ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58()) if err == solana.ErrNoAccountInfo { return false, nil } else if err != nil { @@ -388,7 +388,7 @@ func validateMemoryAccountExists(ctx context.Context, data ocp_data.Provider, ac } func validateMemoryAccountIsResized(ctx context.Context, data ocp_data.Provider, account *common.Account) (bool, error) { - ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58(), solana.CommitmentFinalized) + ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58()) if err == solana.ErrNoAccountInfo { return false, nil } else if err != nil { @@ -407,7 +407,7 @@ func validateMemoryAccountIsResized(ctx context.Context, data ocp_data.Provider, } func validateNonceMemoryAccountPopulated(ctx context.Context, data ocp_data.Provider, account *common.Account) (bool, error) { - ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58(), solana.CommitmentFinalized) + ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58()) if err == solana.ErrNoAccountInfo { return false, nil } else if err != nil { @@ -441,7 +441,7 @@ func validateNonceMemoryAccountPopulated(ctx context.Context, data ocp_data.Prov } func validateNoncePoolInitialized(ctx context.Context, data ocp_data.Provider, account *common.Account) (bool, error) { - ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58(), solana.CommitmentFinalized) + ai, _, err := data.GetBlockchainAccountInfo(ctx, account.PublicKey().ToBase58()) if err == solana.ErrNoAccountInfo { return false, nil } else if err != nil { @@ -462,7 +462,7 @@ func validateNoncePoolInitialized(ctx context.Context, data ocp_data.Provider, a } func (p *runtime) deriveNewAlt(ctx context.Context, accounts *newCurrencyAccounts) error { - recentSlot, err := p.data.GetBlockchainSlot(ctx, solana.CommitmentFinalized) + recentSlot, err := p.data.GetBlockchainSlot(ctx) if err != nil { return err } @@ -677,7 +677,7 @@ func (p *runtime) resizeAndExtendBlockchainAccounts(ctx context.Context, account compute_budget.SetComputeUnitPrice(10_000), } - ai, _, err := p.data.GetBlockchainAccountInfo(ctx, accounts.NonceMemoryAccount.PublicKey().ToBase58(), solana.CommitmentFinalized) + ai, _, err := p.data.GetBlockchainAccountInfo(ctx, accounts.NonceMemoryAccount.PublicKey().ToBase58()) if err != nil { return errors.Wrap(err, "error getting nonce memory account info") } @@ -687,7 +687,7 @@ func (p *runtime) resizeAndExtendBlockchainAccounts(ctx context.Context, account return errors.Wrap(err, "error unmarshalling nonce memory account") } - ai, _, err = p.data.GetBlockchainAccountInfo(ctx, accounts.TimelockMemoryAccount.PublicKey().ToBase58(), solana.CommitmentFinalized) + ai, _, err = p.data.GetBlockchainAccountInfo(ctx, accounts.TimelockMemoryAccount.PublicKey().ToBase58()) if err != nil { return errors.Wrap(err, "error getting timelock memory account info") } @@ -780,7 +780,7 @@ func (p *runtime) resizeAndExtendBlockchainAccounts(ctx context.Context, account } func (p *runtime) populateNonceMemory(ctx context.Context, accounts *newCurrencyAccounts) error { - ai, _, err := p.data.GetBlockchainAccountInfo(ctx, accounts.NonceMemoryAccount.PublicKey().ToBase58(), solana.CommitmentFinalized) + ai, _, err := p.data.GetBlockchainAccountInfo(ctx, accounts.NonceMemoryAccount.PublicKey().ToBase58()) if err != nil { return err } @@ -870,7 +870,7 @@ func (p *runtime) populateNonceMemory(ctx context.Context, accounts *newCurrency } func (p *runtime) initializeNoncePool(ctx context.Context, accounts *newCurrencyAccounts) error { - ai, _, err := p.data.GetBlockchainAccountInfo(ctx, accounts.NonceMemoryAccount.PublicKey().ToBase58(), solana.CommitmentFinalized) + ai, _, err := p.data.GetBlockchainAccountInfo(ctx, accounts.NonceMemoryAccount.PublicKey().ToBase58()) if err != nil { return errors.Wrap(err, "error getting nonce memory account info") } @@ -927,7 +927,7 @@ func (p *runtime) initializeNoncePool(ctx context.Context, accounts *newCurrency } func (p *runtime) addTimelockMemoryAccountToDb(ctx context.Context, accounts *newCurrencyAccounts) error { - ai, _, err := p.data.GetBlockchainAccountInfo(ctx, accounts.TimelockMemoryAccount.PublicKey().ToBase58(), solana.CommitmentFinalized) + ai, _, err := p.data.GetBlockchainAccountInfo(ctx, accounts.TimelockMemoryAccount.PublicKey().ToBase58()) if err != nil { return errors.Wrap(err, "error getting timelock memory account info") } diff --git a/ocp/worker/geyser/external_deposit.go b/ocp/worker/geyser/external_deposit.go index cc4d553..ff36387 100644 --- a/ocp/worker/geyser/external_deposit.go +++ b/ocp/worker/geyser/external_deposit.go @@ -93,7 +93,7 @@ func maybeInitiateExternalDepositIntoVm(ctx context.Context, data ocp_data.Provi return errors.Wrap(err, "error getting vm deposit ata") } - balance, _, err := data.GetBlockchainBalance(ctx, vmDepositAccounts.Ata.PublicKey().ToBase58(), solana.CommitmentFinalized) + balance, _, err := data.GetBlockchainBalance(ctx, vmDepositAccounts.Ata.PublicKey().ToBase58()) if err == solana.ErrNoBalance { return nil } else if err != nil { @@ -177,17 +177,17 @@ func initiateExternalDepositIntoVm(ctx context.Context, data ocp_data.Provider, return errors.Wrap(err, "error submitting transaction to the blockchain") } - var confirmedTxn *solana.ConfirmedTransaction + var finalizedTxn *solana.TransactionWithMeta _, err = retry.Retry( func() error { - confirmedTxn, err = data.GetBlockchainTransaction(ctx, base58.Encode(signature[:]), solana.CommitmentConfirmed) + finalizedTxn, err = data.GetBlockchainTransaction(ctx, base58.Encode(signature[:])) return err }, - waitForConfirmationRetryStrategies..., + waitForFinalizationRetryStrategies..., ) if err != nil { - return errors.Wrap(err, "error getting confirmed transaction") - } else if confirmedTxn.Err != nil || confirmedTxn.Meta.Err != nil { + return errors.Wrap(err, "error getting finalized transaction") + } else if finalizedTxn.Err != nil || finalizedTxn.Meta.Err != nil { return errors.New("transaction failed") } return nil @@ -211,7 +211,6 @@ func findPotentialExternalDepositsIntoVm(ctx context.Context, data ocp_data.Prov history, err := data.GetBlockchainHistory( ctx, vmDepositAta.PublicKey().ToBase58(), - solana.CommitmentConfirmed, // Get signatures faster, which is ok because we'll fetch finalized txn data query.WithLimit(100), query.WithCursor(cursor), ) @@ -563,7 +562,7 @@ func isInitialCurrencyCreatorDeposit(ctx context.Context, data ocp_data.Provider initialSwap := swapRecords[0] - swapTxn, err := data.GetBlockchainTransaction(ctx, initialSwap.TransactionSignature, solana.CommitmentFinalized) + swapTxn, err := data.GetBlockchainTransaction(ctx, initialSwap.TransactionSignature) if err != nil { return false, 0, errors.Wrap(err, "error getting swap transaction") } diff --git a/ocp/worker/geyser/metrics.go b/ocp/worker/geyser/metrics.go index dbc82ef..7b449da 100644 --- a/ocp/worker/geyser/metrics.go +++ b/ocp/worker/geyser/metrics.go @@ -5,7 +5,6 @@ import ( "time" "github.com/code-payments/ocp-server/metrics" - "github.com/code-payments/ocp-server/solana" ) const ( @@ -43,7 +42,7 @@ func (p *runtime) metricsGaugeWorker(ctx context.Context) error { } func (p *runtime) recordSubscriptionStatusPollingEvent(ctx context.Context) { - currentFinalizedSlot, _ := p.data.GetBlockchainSlot(ctx, solana.CommitmentFinalized) + currentFinalizedSlot, _ := p.data.GetBlockchainSlot(ctx) p.metricStatusLock.RLock() defer p.metricStatusLock.RUnlock() diff --git a/ocp/worker/geyser/retry.go b/ocp/worker/geyser/retry.go index 0a502c6..7bba4b1 100644 --- a/ocp/worker/geyser/retry.go +++ b/ocp/worker/geyser/retry.go @@ -13,9 +13,3 @@ var waitForFinalizationRetryStrategies = []retry.Strategy{ retry.Limit(30), retry.Backoff(backoff.Constant(3*time.Second), 3*time.Second), } - -var waitForConfirmationRetryStrategies = []retry.Strategy{ - retry.NonRetriableErrors(context.Canceled), - retry.Limit(10), - retry.Backoff(backoff.Constant(time.Second), time.Second), -} diff --git a/ocp/worker/nonce/pool.go b/ocp/worker/nonce/pool.go index 2df0ca2..8f2312b 100644 --- a/ocp/worker/nonce/pool.go +++ b/ocp/worker/nonce/pool.go @@ -165,7 +165,7 @@ func (p *runtime) handleUnknown(ctx context.Context, record *nonce.Record) error // We're going to the blockchain directly here (super slow btw) // because we don't capture the transaction through history yet (it only // grabs transfer style transactions for KIN accounts). - stx, err := p.data.GetBlockchainTransaction(ctx, record.Signature, solana.CommitmentFinalized) + stx, err := p.data.GetBlockchainTransaction(ctx, record.Signature) if err == solana.ErrSignatureNotFound { // Check the signature for a potential timeout (e.g. if the nonce account // was never created because the blockchain never saw the init/create @@ -180,7 +180,7 @@ func (p *runtime) handleUnknown(ctx context.Context, record *nonce.Record) error return err } - tx, err := transaction.FromConfirmedTransaction(stx) + tx, err := transaction.FromTransactionWithMeta(stx) if err != nil { return err } @@ -210,7 +210,7 @@ func (p *runtime) handleReleased(ctx context.Context, record *nonce.Record) erro // Nonces that exist but we don't yet know their stored blockhash. // Fetch the Solana transaction where the nonce would be consumed - var txn *solana.ConfirmedTransaction + var txn *solana.TransactionWithMeta var err error switch record.Environment { case nonce.EnvironmentSolana: diff --git a/ocp/worker/nonce/util.go b/ocp/worker/nonce/util.go index dc8978e..a1f46a9 100644 --- a/ocp/worker/nonce/util.go +++ b/ocp/worker/nonce/util.go @@ -69,12 +69,12 @@ func (p *runtime) getLatestBlockhash(ctx context.Context) (*solana.Blockhash, er return &bh, nil } -func (p *runtime) getTransaction(ctx context.Context, signature string) (*solana.ConfirmedTransaction, error) { +func (p *runtime) getTransaction(ctx context.Context, signature string) (*solana.TransactionWithMeta, error) { return p.getTransactionFromBlockchain(ctx, signature) } -func (p *runtime) getTransactionFromBlockchain(ctx context.Context, signature string) (*solana.ConfirmedTransaction, error) { - txn, err := p.data.GetBlockchainTransaction(ctx, signature, solana.CommitmentFinalized) +func (p *runtime) getTransactionFromBlockchain(ctx context.Context, signature string) (*solana.TransactionWithMeta, error) { + txn, err := p.data.GetBlockchainTransaction(ctx, signature) if err == solana.ErrSignatureNotFound { return nil, transaction.ErrNotFound } diff --git a/ocp/worker/sequencer/fulfillment_handler.go b/ocp/worker/sequencer/fulfillment_handler.go index 0317a7d..30c7563 100644 --- a/ocp/worker/sequencer/fulfillment_handler.go +++ b/ocp/worker/sequencer/fulfillment_handler.go @@ -810,7 +810,7 @@ func isAccountInitialized(ctx context.Context, data ocp_data.Provider, address s timelockRecord, err := data.GetTimelockByVault(ctx, address) if err == timelock.ErrTimelockNotFound { // Likely not a Code timelock account, so defer to the blockchain - _, _, err := data.GetBlockchainAccountInfo(ctx, address, solana.CommitmentFinalized) + _, _, err := data.GetBlockchainAccountInfo(ctx, address) if err == solana.ErrNoAccountInfo || err == token.ErrAccountNotFound { return false, nil } else if err != nil { diff --git a/ocp/worker/sequencer/utils.go b/ocp/worker/sequencer/utils.go index 4f1cc16..65d646f 100644 --- a/ocp/worker/sequencer/utils.go +++ b/ocp/worker/sequencer/utils.go @@ -150,7 +150,7 @@ func (p *runtime) getTransaction(ctx context.Context, record *fulfillment.Record } func (p *runtime) getTransactionFromBlockchain(ctx context.Context, record *fulfillment.Record) (*transaction.Record, error) { - stx, err := p.data.GetBlockchainTransaction(ctx, *record.Signature, solana.CommitmentFinalized) + stx, err := p.data.GetBlockchainTransaction(ctx, *record.Signature) if err == solana.ErrSignatureNotFound { return nil, transaction.ErrNotFound } @@ -158,7 +158,7 @@ func (p *runtime) getTransactionFromBlockchain(ctx context.Context, record *fulf return nil, err } - tx, err := transaction.FromConfirmedTransaction(stx) + tx, err := transaction.FromTransactionWithMeta(stx) if err != nil { return nil, err } diff --git a/ocp/worker/swap/util.go b/ocp/worker/swap/util.go index 040735e..9d62349 100644 --- a/ocp/worker/swap/util.go +++ b/ocp/worker/swap/util.go @@ -408,7 +408,7 @@ func (p *runtime) markSwapCancelling( }) } -func (p *runtime) markSwapCancelled(ctx context.Context, swapRecord *swap.Record, cancellationTxn *solana.ConfirmedTransaction) error { +func (p *runtime) markSwapCancelled(ctx context.Context, swapRecord *swap.Record, cancellationTxn *solana.TransactionWithMeta) error { toMint, err := common.NewAccountFromPublicKeyString(swapRecord.ToMint) if err != nil { return err @@ -502,7 +502,7 @@ func (p *runtime) markSwapCancelled(ctx context.Context, swapRecord *swap.Record }) } -func (p *runtime) buildRefundRecordsForCancelledSwap(ctx context.Context, swapRecord *swap.Record, cancellationTxn *solana.ConfirmedTransaction) (*intent.Record, *deposit.Record, error) { +func (p *runtime) buildRefundRecordsForCancelledSwap(ctx context.Context, swapRecord *swap.Record, cancellationTxn *solana.TransactionWithMeta) (*intent.Record, *deposit.Record, error) { if cancellationTxn == nil { return nil, nil, errors.New("cancellation transaction is required for refund records") } diff --git a/ocp/worker/swap/worker.go b/ocp/worker/swap/worker.go index 420fb01..8aa01ff 100644 --- a/ocp/worker/swap/worker.go +++ b/ocp/worker/swap/worker.go @@ -146,7 +146,7 @@ func (p *runtime) handleStateFunding(ctx context.Context, record *swap.Record) e case swap.FundingSourceExternalWallet: // Wait for the external wallet funding transaction to be finalized before // transitioning the swap to a funded state - finalizedTxn, err := p.data.GetBlockchainTransaction(ctx, record.FundingId, solana.CommitmentFinalized) + finalizedTxn, err := p.data.GetBlockchainTransaction(ctx, record.FundingId) if err != nil && err != solana.ErrSignatureNotFound { return errors.Wrap(err, "error getting finalized funding transaction") } @@ -177,7 +177,7 @@ func (p *runtime) handleStateFunding(ctx context.Context, record *swap.Record) e switch order.Status { case coinbase.OrderStatusProcessing, coinbase.OrderStatusCompleted: if order.TxHash != "" { - finalizedTxn, err := p.data.GetBlockchainTransaction(ctx, order.TxHash, solana.CommitmentFinalized) + finalizedTxn, err := p.data.GetBlockchainTransaction(ctx, order.TxHash) if err != nil && err != solana.ErrSignatureNotFound { return errors.Wrap(err, "error getting finalized coinbase funding transaction") } @@ -270,7 +270,7 @@ func (p *runtime) handleStateSubmitting(ctx context.Context, record *swap.Record // Monitor for a finalized swap transaction - finalizedTxn, err := p.data.GetBlockchainTransaction(ctx, record.TransactionSignature, solana.CommitmentFinalized) + finalizedTxn, err := p.data.GetBlockchainTransaction(ctx, record.TransactionSignature) if err != nil && err != solana.ErrSignatureNotFound { return errors.Wrap(err, "error getting finalized transaction") } @@ -317,7 +317,7 @@ func (p *runtime) handleStateCancelling(ctx context.Context, record *swap.Record return err } - finalizedTxn, err := p.data.GetBlockchainTransaction(ctx, record.TransactionSignature, solana.CommitmentFinalized) + finalizedTxn, err := p.data.GetBlockchainTransaction(ctx, record.TransactionSignature) if err != nil && err != solana.ErrSignatureNotFound { return errors.Wrap(err, "error getting finalized cancel transaction") } diff --git a/solana/client.go b/solana/client.go index 4f10346..fc5a3d0 100644 --- a/solana/client.go +++ b/solana/client.go @@ -29,21 +29,16 @@ const ( maxSupportedTransactionVersion = 1 ) -type Commitment struct { - Commitment string `json:"commitment"` -} - const ( - confirmationStatusProcessed = "processed" - confirmationStatusConfirmed = "confirmed" confirmationStatusFinalized = "finalized" ) -var ( - CommitmentProcessed = Commitment{Commitment: confirmationStatusProcessed} - CommitmentConfirmed = Commitment{Commitment: confirmationStatusConfirmed} - CommitmentFinalized = Commitment{Commitment: confirmationStatusFinalized} -) +// The client only ever reads finalized state +var finalizedCommitment = struct { + Commitment string `json:"commitment"` +}{ + Commitment: confirmationStatusFinalized, +} var ( ErrNoAccountInfo = errors.New("no account info") @@ -70,18 +65,6 @@ type SignatureStatus struct { ConfirmationStatus string } -func (s SignatureStatus) Confirmed() bool { - if s.Finalized() { - return true - } - - if s.ConfirmationStatus == confirmationStatusConfirmed { - return true - } - - return *s.Confirmations >= 1 -} - func (s SignatureStatus) Finalized() bool { return s.Confirmations == nil || s.ConfirmationStatus == confirmationStatusFinalized } @@ -136,7 +119,7 @@ type TransactionTokenBalances struct { BlockTime *time.Time } -type ConfirmedTransaction struct { +type TransactionWithMeta struct { Slot uint64 BlockTime *time.Time Transaction Transaction @@ -161,7 +144,7 @@ type ProgramAccount struct { // // Reference: https://docs.solana.com/apps/jsonrpc-api type Client interface { - GetAccountInfo(ed25519.PublicKey, Commitment) (AccountInfo, uint64, error) + GetAccountInfo(ed25519.PublicKey) (AccountInfo, uint64, error) GetAccountDataAfterBlock(ed25519.PublicKey, uint64) ([]byte, uint64, error) GetBalance(ed25519.PublicKey) (uint64, error) GetBlock(slot uint64) (*Block, error) @@ -169,12 +152,12 @@ type Client interface { GetLatestBlockhash() (Blockhash, error) GetMinimumBalanceForRentExemption(size uint64) (lamports uint64, err error) GetSignatureStatuses([]Signature) ([]*SignatureStatus, error) - GetSignaturesForAddress(owner ed25519.PublicKey, commitment Commitment, limit uint64, before, until string) ([]*TransactionSignature, error) - GetSlot(Commitment) (uint64, error) - GetTokenAccountBalance(ed25519.PublicKey, Commitment) (uint64, uint64, error) - GetTransaction(Signature, Commitment) (ConfirmedTransaction, error) + GetSignaturesForAddress(owner ed25519.PublicKey, limit uint64, before, until string) ([]*TransactionSignature, error) + GetSlot() (uint64, error) + GetTokenAccountBalance(ed25519.PublicKey) (uint64, uint64, error) + GetTransaction(Signature) (TransactionWithMeta, error) GetTransactionTokenBalances(Signature) (TransactionTokenBalances, error) - SubmitTransaction(Transaction, Commitment) (Signature, error) + SubmitTransaction(Transaction) (Signature, error) } var ( @@ -247,11 +230,11 @@ func (c *client) GetMinimumBalanceForRentExemption(dataSize uint64) (lamports ui return lamports, nil } -func (c *client) GetSlot(commitment Commitment) (slot uint64, err error) { +func (c *client) GetSlot() (slot uint64, err error) { // note: we have to wrap the commitment in an []interface{} otherwise the // solana RPC node complains. Technically this is a violation of the // JSON RPC v2.0 spec. - if err := c.call(&slot, "getSlot", []interface{}{commitment}); err != nil { + if err := c.call(&slot, "getSlot", []interface{}{finalizedCommitment}); err != nil { return 0, errors.Wrapf(err, "getSlot() failed to send request") } @@ -266,7 +249,7 @@ func (c *client) GetLatestBlockhash() (hash Blockhash, err error) { } var resp response - if err := c.call(&resp, "getLatestBlockhash"); err != nil { + if err := c.call(&resp, "getLatestBlockhash", []interface{}{finalizedCommitment}); err != nil { return hash, errors.Wrapf(err, "getLatestBlockhash() failed to send request") } @@ -296,9 +279,11 @@ func (c *client) GetBlock(slot uint64) (block *Block, err error) { } config := struct { + Commitment string `json:"commitment"` Encoding string `json:"encoding"` MaxSupportedTransactionVersion int `json:"maxSupportedTransactionVersion"` }{ + Commitment: confirmationStatusFinalized, Encoding: "base64", MaxSupportedTransactionVersion: maxSupportedTransactionVersion, } @@ -359,7 +344,7 @@ func (c *client) GetBlock(slot uint64) (block *Block, err error) { return block, nil } -func (c *client) GetTransaction(sig Signature, commitment Commitment) (ConfirmedTransaction, error) { +func (c *client) GetTransaction(sig Signature) (TransactionWithMeta, error) { type rpcResponse struct { Slot uint64 `json:"slot"` BlockTime *int64 `json:"blockTime"` @@ -372,21 +357,21 @@ func (c *client) GetTransaction(sig Signature, commitment Commitment) (Confirmed Encoding string `json:"encoding"` MaxSupportedTransactionVersion int `json:"maxSupportedTransactionVersion"` }{ - Commitment: commitment.Commitment, + Commitment: confirmationStatusFinalized, Encoding: "base64", MaxSupportedTransactionVersion: maxSupportedTransactionVersion, } var resp *rpcResponse if err := c.call(&resp, "getTransaction", base58.Encode(sig[:]), config); err != nil { - return ConfirmedTransaction{}, err + return TransactionWithMeta{}, err } if resp == nil { - return ConfirmedTransaction{}, ErrSignatureNotFound + return TransactionWithMeta{}, ErrSignatureNotFound } - txn := ConfirmedTransaction{ + txn := TransactionWithMeta{ Slot: resp.Slot, } @@ -420,9 +405,11 @@ func (c *client) GetTransaction(sig Signature, commitment Commitment) (Confirmed func (c *client) GetTransactionTokenBalances(sig Signature) (TransactionTokenBalances, error) { config := struct { + Commitment string `json:"commitment"` Encoding string `json:"encoding"` MaxSupportedTransactionVersion int `json:"maxSupportedTransactionVersion"` }{ + Commitment: confirmationStatusFinalized, Encoding: "json", // Easier to use json in the event of ever-changing transaction versions MaxSupportedTransactionVersion: maxSupportedTransactionVersion, } @@ -469,7 +456,7 @@ func (c *client) GetTransactionTokenBalances(sig Signature) (TransactionTokenBal func (c *client) GetBalance(account ed25519.PublicKey) (uint64, error) { var resp rpcResponse - if err := c.call(&resp, "getBalance", base58.Encode(account[:]), CommitmentProcessed); err != nil { + if err := c.call(&resp, "getBalance", base58.Encode(account[:]), finalizedCommitment); err != nil { jsonRPCErr, ok := err.(*jsonrpc.RPCError) if !ok { return 0, errors.Wrapf(err, "getBalance() failed to send request") @@ -489,14 +476,14 @@ func (c *client) GetBalance(account ed25519.PublicKey) (uint64, error) { return 0, errors.Errorf("invalid value in response") } -func (c *client) GetTokenAccountBalance(account ed25519.PublicKey, commitment Commitment) (uint64, uint64, error) { +func (c *client) GetTokenAccountBalance(account ed25519.PublicKey) (uint64, uint64, error) { var resp struct { Context struct { Slot int64 `json:"slot"` } `json:"context"` Value TokenAmount `json:"value"` } - if err := c.call(&resp, "getTokenAccountBalance", base58.Encode(account[:]), commitment); err != nil { + if err := c.call(&resp, "getTokenAccountBalance", base58.Encode(account[:]), finalizedCommitment); err != nil { jsonRPCErr, ok := err.(*jsonrpc.RPCError) if !ok { return 0, 0, errors.Wrapf(err, "getTokenAccountBalance() failed to send request") @@ -517,7 +504,7 @@ func (c *client) GetTokenAccountBalance(account ed25519.PublicKey, commitment Co return quarks, uint64(resp.Context.Slot), nil } -func (c *client) SubmitTransaction(txn Transaction, commitment Commitment) (Signature, error) { +func (c *client) SubmitTransaction(txn Transaction) (Signature, error) { sig := txn.Signatures[0] txnBytes, err := txn.Marshal() if err != nil { @@ -533,7 +520,7 @@ func (c *client) SubmitTransaction(txn Transaction, commitment Commitment) (Sign }{ Encoding: "base64", SkipPreflight: true, - PreflightCommitment: commitment.Commitment, + PreflightCommitment: confirmationStatusFinalized, } var sigStr string @@ -565,7 +552,7 @@ func (c *client) SubmitTransaction(txn Transaction, commitment Commitment) (Sign return sig, err } -func (c *client) GetAccountInfo(account ed25519.PublicKey, commitment Commitment) (accountInfo AccountInfo, slot uint64, err error) { +func (c *client) GetAccountInfo(account ed25519.PublicKey) (accountInfo AccountInfo, slot uint64, err error) { type rpcResponse struct { Context struct { Slot uint64 `json:"slot"` @@ -579,10 +566,10 @@ func (c *client) GetAccountInfo(account ed25519.PublicKey, commitment Commitment } rpcConfig := struct { - Commitment Commitment `json:"commitment"` - Encoding string `json:"encoding"` + Commitment string `json:"commitment"` + Encoding string `json:"encoding"` }{ - Commitment: commitment, + Commitment: confirmationStatusFinalized, Encoding: "base64", } @@ -623,7 +610,7 @@ func (c *client) GetAccountDataAfterBlock(account ed25519.PublicKey, slot uint64 Encoding string `json:"encoding"` MinContextSlot uint64 `json:"minContextSlot"` }{ - Commitment: CommitmentFinalized.Commitment, + Commitment: confirmationStatusFinalized, Encoding: "base64", MinContextSlot: slot + 1, } @@ -659,14 +646,14 @@ func (c *client) GetAccountDataAfterBlock(account ed25519.PublicKey, slot uint64 return rawData, resp.Context.Slot, nil } -func (c *client) GetSignaturesForAddress(account ed25519.PublicKey, commitment Commitment, limit uint64, before, until string) ([]*TransactionSignature, error) { +func (c *client) GetSignaturesForAddress(account ed25519.PublicKey, limit uint64, before, until string) ([]*TransactionSignature, error) { req := struct { Commitment string `json:"commitment"` Limit *uint64 `json:"limit"` Before *string `json:"before"` Until *string `json:"until"` }{ - Commitment: commitment.Commitment, + Commitment: confirmationStatusFinalized, } if limit > 0 { diff --git a/solana/client_test.go b/solana/client_test.go index b273363..e07886f 100644 --- a/solana/client_test.go +++ b/solana/client_test.go @@ -17,7 +17,6 @@ func TestSignatureStatus(t *testing.T) { testCases := []struct { s SignatureStatus - confirmed bool finalized bool }{ { @@ -41,7 +40,7 @@ func TestSignatureStatus(t *testing.T) { Slot: 10, ErrorResult: nil, Confirmations: &zero, - ConfirmationStatus: confirmationStatusProcessed, + ConfirmationStatus: "processed", }, }, { @@ -51,16 +50,14 @@ func TestSignatureStatus(t *testing.T) { Confirmations: &one, ConfirmationStatus: "", }, - confirmed: true, }, { s: SignatureStatus{ Slot: 10, ErrorResult: nil, Confirmations: &zero, - ConfirmationStatus: confirmationStatusConfirmed, + ConfirmationStatus: "confirmed", }, - confirmed: true, }, { s: SignatureStatus{ @@ -69,13 +66,11 @@ func TestSignatureStatus(t *testing.T) { Confirmations: &zero, ConfirmationStatus: confirmationStatusFinalized, }, - confirmed: true, finalized: true, }, } for _, tc := range testCases { - assert.Equal(t, tc.confirmed, tc.s.Confirmed()) assert.Equal(t, tc.finalized, tc.s.Finalized()) } } diff --git a/solana/client_with_fallback.go b/solana/client_with_fallback.go index d1866c4..24187c9 100644 --- a/solana/client_with_fallback.go +++ b/solana/client_with_fallback.go @@ -76,10 +76,10 @@ func withFallback2[T1, T2 any](primary, fallback func() (T1, T2, error)) (T1, T2 return fallback() } -func (c *clientWithFallback) GetAccountInfo(account ed25519.PublicKey, commitment Commitment) (AccountInfo, uint64, error) { +func (c *clientWithFallback) GetAccountInfo(account ed25519.PublicKey) (AccountInfo, uint64, error) { return withFallback2( - func() (AccountInfo, uint64, error) { return c.primary.GetAccountInfo(account, commitment) }, - func() (AccountInfo, uint64, error) { return c.fallback.GetAccountInfo(account, commitment) }, + func() (AccountInfo, uint64, error) { return c.primary.GetAccountInfo(account) }, + func() (AccountInfo, uint64, error) { return c.fallback.GetAccountInfo(account) }, ) } @@ -136,35 +136,35 @@ func (c *clientWithFallback) GetSignatureStatuses(sigs []Signature) ([]*Signatur ) } -func (c *clientWithFallback) GetSignaturesForAddress(owner ed25519.PublicKey, commitment Commitment, limit uint64, before, until string) ([]*TransactionSignature, error) { +func (c *clientWithFallback) GetSignaturesForAddress(owner ed25519.PublicKey, limit uint64, before, until string) ([]*TransactionSignature, error) { return withFallback( func() ([]*TransactionSignature, error) { - return c.primary.GetSignaturesForAddress(owner, commitment, limit, before, until) + return c.primary.GetSignaturesForAddress(owner, limit, before, until) }, func() ([]*TransactionSignature, error) { - return c.fallback.GetSignaturesForAddress(owner, commitment, limit, before, until) + return c.fallback.GetSignaturesForAddress(owner, limit, before, until) }, ) } -func (c *clientWithFallback) GetSlot(commitment Commitment) (uint64, error) { +func (c *clientWithFallback) GetSlot() (uint64, error) { return withFallback( - func() (uint64, error) { return c.primary.GetSlot(commitment) }, - func() (uint64, error) { return c.fallback.GetSlot(commitment) }, + func() (uint64, error) { return c.primary.GetSlot() }, + func() (uint64, error) { return c.fallback.GetSlot() }, ) } -func (c *clientWithFallback) GetTokenAccountBalance(account ed25519.PublicKey, commitment Commitment) (uint64, uint64, error) { +func (c *clientWithFallback) GetTokenAccountBalance(account ed25519.PublicKey) (uint64, uint64, error) { return withFallback2( - func() (uint64, uint64, error) { return c.primary.GetTokenAccountBalance(account, commitment) }, - func() (uint64, uint64, error) { return c.fallback.GetTokenAccountBalance(account, commitment) }, + func() (uint64, uint64, error) { return c.primary.GetTokenAccountBalance(account) }, + func() (uint64, uint64, error) { return c.fallback.GetTokenAccountBalance(account) }, ) } -func (c *clientWithFallback) GetTransaction(sig Signature, commitment Commitment) (ConfirmedTransaction, error) { +func (c *clientWithFallback) GetTransaction(sig Signature) (TransactionWithMeta, error) { return withFallback( - func() (ConfirmedTransaction, error) { return c.primary.GetTransaction(sig, commitment) }, - func() (ConfirmedTransaction, error) { return c.fallback.GetTransaction(sig, commitment) }, + func() (TransactionWithMeta, error) { return c.primary.GetTransaction(sig) }, + func() (TransactionWithMeta, error) { return c.fallback.GetTransaction(sig) }, ) } @@ -175,9 +175,9 @@ func (c *clientWithFallback) GetTransactionTokenBalances(sig Signature) (Transac ) } -func (c *clientWithFallback) SubmitTransaction(txn Transaction, commitment Commitment) (Signature, error) { +func (c *clientWithFallback) SubmitTransaction(txn Transaction) (Signature, error) { return withFallback( - func() (Signature, error) { return c.primary.SubmitTransaction(txn, commitment) }, - func() (Signature, error) { return c.fallback.SubmitTransaction(txn, commitment) }, + func() (Signature, error) { return c.primary.SubmitTransaction(txn) }, + func() (Signature, error) { return c.fallback.SubmitTransaction(txn) }, ) } diff --git a/solana/client_with_fallback_test.go b/solana/client_with_fallback_test.go index 790cfaf..d574a04 100644 --- a/solana/client_with_fallback_test.go +++ b/solana/client_with_fallback_test.go @@ -11,9 +11,9 @@ import ( // mockClient implements Client for testing. type mockClient struct { - getSlotFunc func(Commitment) (uint64, error) - getAccountInfoFunc func(ed25519.PublicKey, Commitment) (AccountInfo, uint64, error) - submitTransactionFunc func(Transaction, Commitment) (Signature, error) + getSlotFunc func() (uint64, error) + getAccountInfoFunc func(ed25519.PublicKey) (AccountInfo, uint64, error) + submitTransactionFunc func(Transaction) (Signature, error) getBalanceFunc func(ed25519.PublicKey) (uint64, error) getBlockFunc func(uint64) (*Block, error) getLatestBlockhashFunc func() (Blockhash, error) @@ -21,26 +21,26 @@ type mockClient struct { callCount int } -func (m *mockClient) GetSlot(c Commitment) (uint64, error) { +func (m *mockClient) GetSlot() (uint64, error) { m.callCount++ if m.getSlotFunc != nil { - return m.getSlotFunc(c) + return m.getSlotFunc() } return 0, nil } -func (m *mockClient) GetAccountInfo(pk ed25519.PublicKey, c Commitment) (AccountInfo, uint64, error) { +func (m *mockClient) GetAccountInfo(pk ed25519.PublicKey) (AccountInfo, uint64, error) { m.callCount++ if m.getAccountInfoFunc != nil { - return m.getAccountInfoFunc(pk, c) + return m.getAccountInfoFunc(pk) } return AccountInfo{}, 0, nil } -func (m *mockClient) SubmitTransaction(tx Transaction, c Commitment) (Signature, error) { +func (m *mockClient) SubmitTransaction(tx Transaction) (Signature, error) { m.callCount++ if m.submitTransactionFunc != nil { - return m.submitTransactionFunc(tx, c) + return m.submitTransactionFunc(tx) } return Signature{}, nil } @@ -86,17 +86,17 @@ func (m *mockClient) GetSignatureStatuses([]Signature) ([]*SignatureStatus, erro m.callCount++ return nil, nil } -func (m *mockClient) GetSignaturesForAddress(ed25519.PublicKey, Commitment, uint64, string, string) ([]*TransactionSignature, error) { +func (m *mockClient) GetSignaturesForAddress(ed25519.PublicKey, uint64, string, string) ([]*TransactionSignature, error) { m.callCount++ return nil, nil } -func (m *mockClient) GetTokenAccountBalance(ed25519.PublicKey, Commitment) (uint64, uint64, error) { +func (m *mockClient) GetTokenAccountBalance(ed25519.PublicKey) (uint64, uint64, error) { m.callCount++ return 0, 0, nil } -func (m *mockClient) GetTransaction(Signature, Commitment) (ConfirmedTransaction, error) { +func (m *mockClient) GetTransaction(Signature) (TransactionWithMeta, error) { m.callCount++ - return ConfirmedTransaction{}, nil + return TransactionWithMeta{}, nil } func (m *mockClient) GetTransactionTokenBalances(Signature) (TransactionTokenBalances, error) { m.callCount++ @@ -105,14 +105,14 @@ func (m *mockClient) GetTransactionTokenBalances(Signature) (TransactionTokenBal func TestClientWithFallback_PrimarySuccess(t *testing.T) { primary := &mockClient{ - getSlotFunc: func(c Commitment) (uint64, error) { + getSlotFunc: func() (uint64, error) { return 42, nil }, } fallback := &mockClient{} client := NewWithFallbackFromClients(primary, fallback) - slot, err := client.GetSlot(CommitmentFinalized) + slot, err := client.GetSlot() require.NoError(t, err) assert.Equal(t, uint64(42), slot) @@ -122,18 +122,18 @@ func TestClientWithFallback_PrimarySuccess(t *testing.T) { func TestClientWithFallback_UnexpectedError_UsesFallback(t *testing.T) { primary := &mockClient{ - getSlotFunc: func(c Commitment) (uint64, error) { + getSlotFunc: func() (uint64, error) { return 0, errors.New("connection refused") }, } fallback := &mockClient{ - getSlotFunc: func(c Commitment) (uint64, error) { + getSlotFunc: func() (uint64, error) { return 99, nil }, } client := NewWithFallbackFromClients(primary, fallback) - slot, err := client.GetSlot(CommitmentFinalized) + slot, err := client.GetSlot() require.NoError(t, err) assert.Equal(t, uint64(99), slot) @@ -217,18 +217,18 @@ func TestClientWithFallback_BothFail_ReturnsFallbackError(t *testing.T) { fallbackErr := errors.New("fallback down") primary := &mockClient{ - getSlotFunc: func(c Commitment) (uint64, error) { + getSlotFunc: func() (uint64, error) { return 0, primaryErr }, } fallback := &mockClient{ - getSlotFunc: func(c Commitment) (uint64, error) { + getSlotFunc: func() (uint64, error) { return 0, fallbackErr }, } client := NewWithFallbackFromClients(primary, fallback) - _, err := client.GetSlot(CommitmentFinalized) + _, err := client.GetSlot() assert.ErrorIs(t, err, fallbackErr) assert.Equal(t, 1, primary.callCount) @@ -237,18 +237,18 @@ func TestClientWithFallback_BothFail_ReturnsFallbackError(t *testing.T) { func TestClientWithFallback_MultiReturn_UsesFallback(t *testing.T) { primary := &mockClient{ - getAccountInfoFunc: func(pk ed25519.PublicKey, c Commitment) (AccountInfo, uint64, error) { + getAccountInfoFunc: func(pk ed25519.PublicKey) (AccountInfo, uint64, error) { return AccountInfo{}, 0, errors.New("rpc error") }, } fallback := &mockClient{ - getAccountInfoFunc: func(pk ed25519.PublicKey, c Commitment) (AccountInfo, uint64, error) { + getAccountInfoFunc: func(pk ed25519.PublicKey) (AccountInfo, uint64, error) { return AccountInfo{Lamports: 1000}, 50, nil }, } client := NewWithFallbackFromClients(primary, fallback) - info, slot, err := client.GetAccountInfo(ed25519.PublicKey{}, CommitmentFinalized) + info, slot, err := client.GetAccountInfo(ed25519.PublicKey{}) require.NoError(t, err) assert.Equal(t, uint64(1000), info.Lamports) @@ -259,20 +259,20 @@ func TestClientWithFallback_MultiReturn_UsesFallback(t *testing.T) { func TestClientWithFallback_SubmitTransaction_UsesFallback(t *testing.T) { primary := &mockClient{ - submitTransactionFunc: func(tx Transaction, c Commitment) (Signature, error) { + submitTransactionFunc: func(tx Transaction) (Signature, error) { return Signature{}, errors.New("connection timeout") }, } expectedSig := Signature{1, 2, 3} fallback := &mockClient{ - submitTransactionFunc: func(tx Transaction, c Commitment) (Signature, error) { + submitTransactionFunc: func(tx Transaction) (Signature, error) { return expectedSig, nil }, } client := NewWithFallbackFromClients(primary, fallback) - sig, err := client.SubmitTransaction(Transaction{}, CommitmentProcessed) + sig, err := client.SubmitTransaction(Transaction{}) require.NoError(t, err) assert.Equal(t, expectedSig, sig) diff --git a/solana/token/client.go b/solana/token/client.go index 0efa4ae..76e5b67 100644 --- a/solana/token/client.go +++ b/solana/token/client.go @@ -32,8 +32,8 @@ func NewClient(sc solana.Client) *Client { // // If the account is not initialized, or belongs to a different // mint, then ErrInvalidTokenAccount is returned. -func (c *Client) GetAccount(accountID, mintID ed25519.PublicKey, commitment solana.Commitment) (*Account, error) { - accountInfo, _, err := c.sc.GetAccountInfo(accountID, commitment) +func (c *Client) GetAccount(accountID, mintID ed25519.PublicKey) (*Account, error) { + accountInfo, _, err := c.sc.GetAccountInfo(accountID) if err == solana.ErrNoAccountInfo { return nil, ErrAccountNotFound } else if err != nil { From 544527cfb731eeac0b5ba90f309e86cab84f0043 Mon Sep 17 00:00:00 2001 From: jeffyanta Date: Wed, 21 Oct 2026 15:40:10 -0400 Subject: [PATCH 2/3] Update Solana pollers to be more aggressive --- ocp/transaction/submit.go | 4 ++-- ocp/worker/geyser/retry.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ocp/transaction/submit.go b/ocp/transaction/submit.go index 3df2aa5..48629dd 100644 --- a/ocp/transaction/submit.go +++ b/ocp/transaction/submit.go @@ -45,8 +45,8 @@ func SubmitAndWaitForFinalization(ctx context.Context, data ocp_data.BlockchainD return nil }, retry.NonRetriableErrors(context.Canceled, ErrTransactionFailed), - retry.Backoff(backoff.Constant(time.Second), time.Second), - retry.Limit(60), + retry.Backoff(backoff.Constant(250*time.Millisecond), 250*time.Millisecond), + retry.Limit(30), ) return err } diff --git a/ocp/worker/geyser/retry.go b/ocp/worker/geyser/retry.go index 7bba4b1..fc2e537 100644 --- a/ocp/worker/geyser/retry.go +++ b/ocp/worker/geyser/retry.go @@ -11,5 +11,5 @@ import ( var waitForFinalizationRetryStrategies = []retry.Strategy{ retry.NonRetriableErrors(context.Canceled), retry.Limit(30), - retry.Backoff(backoff.Constant(3*time.Second), 3*time.Second), + retry.Backoff(backoff.Constant(250*time.Millisecond), 250*time.Millisecond), } From fca2819a31d3bf719d8fb08518d7fa884e859867 Mon Sep 17 00:00:00 2001 From: jeffyanta Date: Wed, 21 Oct 2026 20:08:10 -0400 Subject: [PATCH 3/3] Remove GetSignatureStatuses --- ocp/data/blockchain.go | 13 ----- solana/client.go | 73 ----------------------------- solana/client_test.go | 63 ------------------------- solana/client_with_fallback.go | 7 --- solana/client_with_fallback_test.go | 4 -- 5 files changed, 160 deletions(-) diff --git a/ocp/data/blockchain.go b/ocp/data/blockchain.go index 10e1d86..517f628 100644 --- a/ocp/data/blockchain.go +++ b/ocp/data/blockchain.go @@ -25,7 +25,6 @@ type BlockchainData interface { GetBlockchainHistory(ctx context.Context, account string, opts ...query.Option) ([]*solana.TransactionSignature, error) GetBlockchainMinimumBalanceForRentExemption(ctx context.Context, size uint64) (uint64, error) GetBlockchainLatestBlockhash(ctx context.Context) (solana.Blockhash, error) - GetBlockchainSignatureStatuses(ctx context.Context, signatures []solana.Signature) ([]*solana.SignatureStatus, error) GetBlockchainSlot(ctx context.Context) (uint64, error) GetBlockchainTokenAccountInfo(ctx context.Context, account, mint string) (*token.Account, error) GetBlockchainTransaction(ctx context.Context, sig string) (*solana.TransactionWithMeta, error) @@ -198,18 +197,6 @@ func (dp *BlockchainProvider) GetBlockchainTransaction(ctx context.Context, sig return &res, nil } -func (dp *BlockchainProvider) GetBlockchainSignatureStatuses(ctx context.Context, signatures []solana.Signature) ([]*solana.SignatureStatus, error) { - tracer := metrics.TraceMethodCall(ctx, blockchainProviderMetricsName, "GetBlockchainSignatureStatuses") - defer tracer.End() - - res, err := dp.sc.GetSignatureStatuses(signatures) - - if err != nil { - tracer.OnError(err) - } - return res, err -} - func (dp *BlockchainProvider) GetBlockchainLatestBlockhash(ctx context.Context) (solana.Blockhash, error) { tracer := metrics.TraceMethodCall(ctx, blockchainProviderMetricsName, "GetBlockchainLatestBlockhash") defer tracer.End() diff --git a/solana/client.go b/solana/client.go index fc5a3d0..a5bebf9 100644 --- a/solana/client.go +++ b/solana/client.go @@ -56,19 +56,6 @@ type AccountInfo struct { Executable bool } -type SignatureStatus struct { - Slot uint64 - ErrorResult *TransactionError - - // Confirmations will be nil if the transaction has been rooted. - Confirmations *int - ConfirmationStatus string -} - -func (s SignatureStatus) Finalized() bool { - return s.Confirmations == nil || s.ConfirmationStatus == confirmationStatusFinalized -} - type Block struct { Hash []byte PrevHash []byte @@ -151,7 +138,6 @@ type Client interface { GetFilteredProgramAccounts(program ed25519.PublicKey, offset uint, filterValue []byte) ([]ProgramAccount, uint64, error) GetLatestBlockhash() (Blockhash, error) GetMinimumBalanceForRentExemption(size uint64) (lamports uint64, err error) - GetSignatureStatuses([]Signature) ([]*SignatureStatus, error) GetSignaturesForAddress(owner ed25519.PublicKey, limit uint64, before, until string) ([]*TransactionSignature, error) GetSlot() (uint64, error) GetTokenAccountBalance(ed25519.PublicKey) (uint64, uint64, error) @@ -720,65 +706,6 @@ func (c *client) GetSignaturesForAddress(account ed25519.PublicKey, limit uint64 return result, nil } -func (c *client) GetSignatureStatuses(sigs []Signature) ([]*SignatureStatus, error) { - b58Sigs := make([]string, len(sigs)) - for i := range sigs { - b58Sigs[i] = base58.Encode(sigs[i][:]) - } - - req := struct { - SearchTransactionHistory bool `json:"searchTransactionHistory"` - }{ - SearchTransactionHistory: true, - } - - type signatureStatus struct { - Slot uint64 `json:"slot"` - Confirmations *int `json:"confirmations"` - ConfirmationStatus string `json:"confirmationStatus"` - Err json.RawMessage `json:"err"` - } - - type rpcResp struct { - Context struct { - Slot int `json:"slot"` - } `json:"context"` - Value []*signatureStatus `json:"value"` - } - - var resp rpcResp - if err := c.call(&resp, "getSignatureStatuses", b58Sigs, req); err != nil { - return nil, err - } - - statuses := make([]*SignatureStatus, len(sigs)) - for i, v := range resp.Value { - if v == nil { - continue - } - - statuses[i] = &SignatureStatus{} - statuses[i].Confirmations = v.Confirmations - statuses[i].ConfirmationStatus = v.ConfirmationStatus - statuses[i].Slot = v.Slot - - if len(v.Err) > 0 { - var txError interface{} - err := json.NewDecoder(bytes.NewBuffer(v.Err)).Decode(&txError) - if err != nil { - return nil, errors.Wrap(err, "failed to parse transaction result") - } - - statuses[i].ErrorResult, err = ParseTransactionError(txError) - if err != nil { - return nil, errors.Wrap(err, "failed to parse transaction result") - } - } - } - - return statuses, nil -} - func (c *client) GetFilteredProgramAccounts(program ed25519.PublicKey, offset uint, filterValue []byte) ([]ProgramAccount, uint64, error) { type memcmpFilter struct { Offset uint `json:"offset"` diff --git a/solana/client_test.go b/solana/client_test.go index e07886f..16f6ecb 100644 --- a/solana/client_test.go +++ b/solana/client_test.go @@ -12,69 +12,6 @@ import ( "github.com/stretchr/testify/require" ) -func TestSignatureStatus(t *testing.T) { - zero, one := 0, 1 - - testCases := []struct { - s SignatureStatus - finalized bool - }{ - { - s: SignatureStatus{ - Slot: 10, - ErrorResult: nil, - Confirmations: &zero, - ConfirmationStatus: "", - }, - }, - { - s: SignatureStatus{ - Slot: 10, - ErrorResult: nil, - Confirmations: &zero, - ConfirmationStatus: "random", - }, - }, - { - s: SignatureStatus{ - Slot: 10, - ErrorResult: nil, - Confirmations: &zero, - ConfirmationStatus: "processed", - }, - }, - { - s: SignatureStatus{ - Slot: 10, - ErrorResult: nil, - Confirmations: &one, - ConfirmationStatus: "", - }, - }, - { - s: SignatureStatus{ - Slot: 10, - ErrorResult: nil, - Confirmations: &zero, - ConfirmationStatus: "confirmed", - }, - }, - { - s: SignatureStatus{ - Slot: 10, - ErrorResult: nil, - Confirmations: &zero, - ConfirmationStatus: confirmationStatusFinalized, - }, - finalized: true, - }, - } - - for _, tc := range testCases { - assert.Equal(t, tc.finalized, tc.s.Finalized()) - } -} - func TestGetAccountDataAfterBlock(t *testing.T) { account := make(ed25519.PublicKey, ed25519.PublicKeySize) data := []byte{1, 2, 3} diff --git a/solana/client_with_fallback.go b/solana/client_with_fallback.go index 24187c9..5b6f571 100644 --- a/solana/client_with_fallback.go +++ b/solana/client_with_fallback.go @@ -129,13 +129,6 @@ func (c *clientWithFallback) GetMinimumBalanceForRentExemption(size uint64) (uin ) } -func (c *clientWithFallback) GetSignatureStatuses(sigs []Signature) ([]*SignatureStatus, error) { - return withFallback( - func() ([]*SignatureStatus, error) { return c.primary.GetSignatureStatuses(sigs) }, - func() ([]*SignatureStatus, error) { return c.fallback.GetSignatureStatuses(sigs) }, - ) -} - func (c *clientWithFallback) GetSignaturesForAddress(owner ed25519.PublicKey, limit uint64, before, until string) ([]*TransactionSignature, error) { return withFallback( func() ([]*TransactionSignature, error) { diff --git a/solana/client_with_fallback_test.go b/solana/client_with_fallback_test.go index d574a04..38f902f 100644 --- a/solana/client_with_fallback_test.go +++ b/solana/client_with_fallback_test.go @@ -82,10 +82,6 @@ func (m *mockClient) GetMinimumBalanceForRentExemption(uint64) (uint64, error) { m.callCount++ return 0, nil } -func (m *mockClient) GetSignatureStatuses([]Signature) ([]*SignatureStatus, error) { - m.callCount++ - return nil, nil -} func (m *mockClient) GetSignaturesForAddress(ed25519.PublicKey, uint64, string, string) ([]*TransactionSignature, error) { m.callCount++ return nil, nil