Skip to content

Commit 32a32b4

Browse files
committed
fix(rpc): handle EncodingJSON response in GetBlockWithOpts
1 parent c84bca0 commit 32a32b4

2 files changed

Lines changed: 27 additions & 5 deletions

File tree

rpc/client_test.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -471,14 +471,16 @@ func TestClient_GetBlockWithOpts(t *testing.T) {
471471
}
472472

473473
func TestClient_GetBlockWithOpts_EncodingJSON(t *testing.T) {
474-
responseBody := `{}`
474+
// Full EncodingJSON response: transactions are JSON objects, not base64 arrays.
475+
// System program (11111111111111111111111111111111) used as second account.
476+
responseBody := `{"blockHeight":100,"blockTime":1625227950,"blockhash":"5M77sHdwzH6rckuQwF8HL1w52n7hjrh4GVTFiF6T8QyB","parentSlot":99,"previousBlockhash":"Aq9jSXe1jRzfiaBcRFLe4wm7j499vWVEeFQrq5nnXfZN","rewards":[],"transactions":[{"meta":{"err":null,"fee":5000,"innerInstructions":[],"logMessages":[],"postBalances":[441866063495,1],"postTokenBalances":[],"preBalances":[441866068495,1],"preTokenBalances":[],"rewards":[],"status":{"Ok":null}},"transaction":{"message":{"accountKeys":["EVd8FFVB54svYdZdG6hH4F4hTbqre5mpQ7XyF5rKUmes","11111111111111111111111111111111"],"header":{"numRequiredSignatures":1,"numReadonlySignedAccounts":0,"numReadonlyUnsignedAccounts":1},"recentBlockhash":"Aq9jSXe1jRzfiaBcRFLe4wm7j499vWVEeFQrq5nnXfZN","instructions":[{"accounts":[0,1],"data":"3Bxs4ThLFRfx6J7z","programIdIndex":1}]},"signatures":["D8emaP3CaepSGigD3TCrev7j67yPLMi82qfzTb9iZYPxHcCmm6sQBKTU4bzAee4445zbnbWduVAZ87WfbWbXoAU"]},"version":"legacy"}]}`
475477
server, closer := mockJSONRPC(t, stdjson.RawMessage(wrapIntoRPC(responseBody)))
476478
defer closer()
477479

478480
client := New(server.URL)
479481

480482
block := 42
481-
_, err := client.GetBlockWithOpts(
483+
out, err := client.GetBlockWithOpts(
482484
context.Background(),
483485
uint64(block),
484486
&GetBlockOpts{
@@ -506,6 +508,13 @@ func TestClient_GetBlockWithOpts_EncodingJSON(t *testing.T) {
506508
},
507509
reqBody,
508510
)
511+
512+
require.Len(t, out.Transactions, 1)
513+
tx, err := out.Transactions[0].GetTransaction()
514+
require.NoError(t, err)
515+
require.Len(t, tx.Signatures, 1)
516+
require.Len(t, tx.Message.AccountKeys, 2)
517+
assert.Equal(t, solana.MustPublicKeyFromBase58("EVd8FFVB54svYdZdG6hH4F4hTbqre5mpQ7XyF5rKUmes"), tx.Message.AccountKeys[0])
509518
}
510519

511520
func TestClient_GetBlockWithOpts_AccountsMode(t *testing.T) {
@@ -603,7 +612,7 @@ func TestClient_GetBlockWithOpts_AccountsMode_GetTransactionFails(t *testing.T)
603612

604613
require.Len(t, out.Transactions, 1)
605614

606-
// GetTransaction should fail — no binary data
615+
// GetTransaction should fail — accounts mode returns JSON without a message field.
607616
_, err = out.Transactions[0].GetTransaction()
608617
assert.Error(t, err)
609618

rpc/types.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,22 @@ func (twm TransactionWithMeta) MustGetTransaction() *solana.Transaction {
116116
}
117117

118118
func (twm TransactionWithMeta) GetTransaction() (*solana.Transaction, error) {
119+
if twm.Transaction == nil {
120+
return nil, fmt.Errorf("transaction is nil")
121+
}
122+
// EncodingJSON: the RPC returned a JSON object — unmarshal directly.
123+
if raw := twm.Transaction.GetRawJSON(); raw != nil {
124+
var tx solana.Transaction
125+
if err := json.Unmarshal(raw, &tx); err != nil {
126+
return nil, err
127+
}
128+
if tx.Message.AccountKeys == nil {
129+
return nil, fmt.Errorf("transaction has no message: block may have been fetched with transactionDetails=accounts; use GetAccountKeys instead")
130+
}
131+
return &tx, nil
132+
}
119133
tx := new(solana.Transaction)
120-
err := tx.UnmarshalWithDecoder(bin.NewBinDecoder(twm.Transaction.GetBinary()))
121-
if err != nil {
134+
if err := tx.UnmarshalWithDecoder(bin.NewBinDecoder(twm.Transaction.GetBinary())); err != nil {
122135
return nil, err
123136
}
124137
return tx, nil

0 commit comments

Comments
 (0)