Skip to content

Commit c50ea11

Browse files
Marshal blocks and transactions inside API calls (#2153)
1 parent 0ac1937 commit c50ea11

File tree

5 files changed

+112
-98
lines changed

5 files changed

+112
-98
lines changed

api/common_args_responses.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
package api
55

66
import (
7+
stdjson "encoding/json"
8+
79
"github.com/ava-labs/avalanchego/ids"
810
"github.com/ava-labs/avalanchego/utils/formatting"
911
"github.com/ava-labs/avalanchego/utils/json"
@@ -75,7 +77,7 @@ type GetBlockByHeightArgs struct {
7577

7678
// GetBlockResponse is the response object for the GetBlock API.
7779
type GetBlockResponse struct {
78-
Block interface{} `json:"block"`
80+
Block stdjson.RawMessage `json:"block"`
7981
// If GetBlockResponse.Encoding is formatting.Hex, GetBlockResponse.Block is
8082
// the string representation of the block under hex encoding.
8183
// If GetBlockResponse.Encoding is formatting.JSON, GetBlockResponse.Block
@@ -105,7 +107,7 @@ type GetTxReply struct {
105107
// the tx under hex encoding.
106108
// If [GetTxArgs.Encoding] is [JSON], [Tx] is the actual tx, which will be
107109
// returned as JSON to the caller.
108-
Tx interface{} `json:"tx"`
110+
Tx stdjson.RawMessage `json:"tx"`
109111
Encoding formatting.Encoding `json:"encoding"`
110112
}
111113

vms/avm/service.go

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
"math"
1010
"net/http"
1111

12+
stdjson "encoding/json"
13+
1214
"go.uber.org/zap"
1315

1416
"github.com/ava-labs/avalanchego/api"
@@ -79,6 +81,7 @@ func (s *Service) GetBlock(_ *http.Request, args *api.GetBlockArgs, reply *api.G
7981
}
8082
reply.Encoding = args.Encoding
8183

84+
var result any
8285
if args.Encoding == formatting.JSON {
8386
block.InitCtx(s.vm.ctx)
8487
for _, tx := range block.Txs() {
@@ -92,16 +95,16 @@ func (s *Service) GetBlock(_ *http.Request, args *api.GetBlockArgs, reply *api.G
9295
return err
9396
}
9497
}
95-
reply.Block = block
96-
return nil
97-
}
98-
99-
reply.Block, err = formatting.Encode(args.Encoding, block.Bytes())
100-
if err != nil {
101-
return fmt.Errorf("couldn't encode block %s as string: %w", args.BlockID, err)
98+
result = block
99+
} else {
100+
result, err = formatting.Encode(args.Encoding, block.Bytes())
101+
if err != nil {
102+
return fmt.Errorf("couldn't encode block %s as string: %w", args.BlockID, err)
103+
}
102104
}
103105

104-
return nil
106+
reply.Block, err = stdjson.Marshal(result)
107+
return err
105108
}
106109

107110
// GetBlockByHeight returns the block at the given height.
@@ -130,6 +133,7 @@ func (s *Service) GetBlockByHeight(_ *http.Request, args *api.GetBlockByHeightAr
130133
return fmt.Errorf("couldn't get block with id %s: %w", blockID, err)
131134
}
132135

136+
var result any
133137
if args.Encoding == formatting.JSON {
134138
block.InitCtx(s.vm.ctx)
135139
for _, tx := range block.Txs() {
@@ -143,16 +147,16 @@ func (s *Service) GetBlockByHeight(_ *http.Request, args *api.GetBlockByHeightAr
143147
return err
144148
}
145149
}
146-
reply.Block = block
147-
return nil
148-
}
149-
150-
reply.Block, err = formatting.Encode(args.Encoding, block.Bytes())
151-
if err != nil {
152-
return fmt.Errorf("couldn't encode block %s as string: %w", blockID, err)
150+
result = block
151+
} else {
152+
result, err = formatting.Encode(args.Encoding, block.Bytes())
153+
if err != nil {
154+
return fmt.Errorf("couldn't encode block %s as string: %w", blockID, err)
155+
}
153156
}
154157

155-
return nil
158+
reply.Block, err = stdjson.Marshal(result)
159+
return err
156160
}
157161

158162
// GetHeight returns the height of the last accepted block.
@@ -320,23 +324,26 @@ func (s *Service) GetTx(_ *http.Request, args *api.GetTxArgs, reply *api.GetTxRe
320324
if err != nil {
321325
return err
322326
}
323-
324327
reply.Encoding = args.Encoding
328+
329+
var result any
325330
if args.Encoding == formatting.JSON {
326-
reply.Tx = tx
327-
return tx.Unsigned.Visit(&txInit{
331+
err = tx.Unsigned.Visit(&txInit{
328332
tx: tx,
329333
ctx: s.vm.ctx,
330334
typeToFxIndex: s.vm.typeToFxIndex,
331335
fxs: s.vm.fxs,
332336
})
337+
result = tx
338+
} else {
339+
result, err = formatting.Encode(args.Encoding, tx.Bytes())
333340
}
334-
335-
reply.Tx, err = formatting.Encode(args.Encoding, tx.Bytes())
336341
if err != nil {
337-
return fmt.Errorf("couldn't encode tx as string: %w", err)
342+
return err
338343
}
339-
return nil
344+
345+
reply.Tx, err = stdjson.Marshal(result)
346+
return err
340347
}
341348

342349
// GetUTXOs gets all utxos for passed in addresses

vms/avm/service_test.go

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -481,9 +481,14 @@ func TestServiceGetTx(t *testing.T) {
481481

482482
reply := api.GetTxReply{}
483483
require.NoError(env.service.GetTx(nil, &api.GetTxArgs{
484-
TxID: txID,
484+
TxID: txID,
485+
Encoding: formatting.Hex,
485486
}, &reply))
486-
txBytes, err := formatting.Decode(reply.Encoding, reply.Tx.(string))
487+
488+
var txStr string
489+
require.NoError(stdjson.Unmarshal(reply.Tx, &txStr))
490+
491+
txBytes, err := formatting.Decode(reply.Encoding, txStr)
487492
require.NoError(err)
488493
require.Equal(env.genesisTx.Bytes(), txBytes)
489494
}
@@ -507,9 +512,7 @@ func TestServiceGetTxJSON_BaseTx(t *testing.T) {
507512
}, &reply))
508513

509514
require.Equal(reply.Encoding, formatting.JSON)
510-
jsonTxBytes, err := stdjson.Marshal(reply.Tx)
511-
require.NoError(err)
512-
jsonString := string(jsonTxBytes)
515+
jsonString := string(reply.Tx)
513516
require.Contains(jsonString, `"memo":"0x0102030405060708"`)
514517
require.Contains(jsonString, `"inputs":[{"txID":"2XGxUr7VF7j1iwUp2aiGe4b6Ue2yyNghNS1SuNTNmZ77dPpXFZ","outputIndex":2,"assetID":"2XGxUr7VF7j1iwUp2aiGe4b6Ue2yyNghNS1SuNTNmZ77dPpXFZ","fxID":"spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ","input":{"amount":50000,"signatureIndices":[0]}}]`)
515518
require.Contains(jsonString, `"outputs":[{"assetID":"2XGxUr7VF7j1iwUp2aiGe4b6Ue2yyNghNS1SuNTNmZ77dPpXFZ","fxID":"spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ","output":{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"],"amount":49000,"locktime":0,"threshold":1}}]`)
@@ -534,9 +537,7 @@ func TestServiceGetTxJSON_ExportTx(t *testing.T) {
534537
}, &reply))
535538

536539
require.Equal(reply.Encoding, formatting.JSON)
537-
jsonTxBytes, err := stdjson.Marshal(reply.Tx)
538-
require.NoError(err)
539-
jsonString := string(jsonTxBytes)
540+
jsonString := string(reply.Tx)
540541
require.Contains(jsonString, `"inputs":[{"txID":"2XGxUr7VF7j1iwUp2aiGe4b6Ue2yyNghNS1SuNTNmZ77dPpXFZ","outputIndex":2,"assetID":"2XGxUr7VF7j1iwUp2aiGe4b6Ue2yyNghNS1SuNTNmZ77dPpXFZ","fxID":"spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ","input":{"amount":50000,"signatureIndices":[0]}}]`)
541542
require.Contains(jsonString, `"exportedOutputs":[{"assetID":"2XGxUr7VF7j1iwUp2aiGe4b6Ue2yyNghNS1SuNTNmZ77dPpXFZ","fxID":"spdxUxVJQbX85MGxMHbKw1sHxMnSqJ3QBzDyDYEP3h6TLuxqQ","output":{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"],"amount":49000,"locktime":0,"threshold":1}}]}`)
542543
}
@@ -566,9 +567,7 @@ func TestServiceGetTxJSON_CreateAssetTx(t *testing.T) {
566567
}, &reply))
567568

568569
require.Equal(reply.Encoding, formatting.JSON)
569-
jsonTxBytes, err := stdjson.Marshal(reply.Tx)
570-
require.NoError(err)
571-
jsonString := string(jsonTxBytes)
570+
jsonString := string(reply.Tx)
572571

573572
// contains the address in the right format
574573
require.Contains(jsonString, `"outputs":[{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"],"groupID":1,"locktime":0,"threshold":1},{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"],"groupID":2,"locktime":0,"threshold":1}]}`)
@@ -605,9 +604,7 @@ func TestServiceGetTxJSON_OperationTxWithNftxMintOp(t *testing.T) {
605604
}, &reply))
606605

607606
require.Equal(reply.Encoding, formatting.JSON)
608-
jsonTxBytes, err := stdjson.Marshal(reply.Tx)
609-
require.NoError(err)
610-
jsonString := string(jsonTxBytes)
607+
jsonString := string(reply.Tx)
611608
// assert memo and payload are in hex
612609
require.Contains(jsonString, `"memo":"0x"`)
613610
require.Contains(jsonString, `"payload":"0x68656c6c6f"`)
@@ -651,9 +648,7 @@ func TestServiceGetTxJSON_OperationTxWithMultipleNftxMintOp(t *testing.T) {
651648
}, &reply))
652649

653650
require.Equal(reply.Encoding, formatting.JSON)
654-
jsonTxBytes, err := stdjson.Marshal(reply.Tx)
655-
require.NoError(err)
656-
jsonString := string(jsonTxBytes)
651+
jsonString := string(reply.Tx)
657652

658653
// contains the address in the right format
659654
require.Contains(jsonString, `"outputs":[{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"]`)
@@ -693,9 +688,7 @@ func TestServiceGetTxJSON_OperationTxWithSecpMintOp(t *testing.T) {
693688
}, &reply))
694689

695690
require.Equal(reply.Encoding, formatting.JSON)
696-
jsonTxBytes, err := stdjson.Marshal(reply.Tx)
697-
require.NoError(err)
698-
jsonString := string(jsonTxBytes)
691+
jsonString := string(reply.Tx)
699692

700693
// ensure memo is in hex
701694
require.Contains(jsonString, `"memo":"0x"`)
@@ -741,9 +734,7 @@ func TestServiceGetTxJSON_OperationTxWithMultipleSecpMintOp(t *testing.T) {
741734
}, &reply))
742735

743736
require.Equal(reply.Encoding, formatting.JSON)
744-
jsonTxBytes, err := stdjson.Marshal(reply.Tx)
745-
require.NoError(err)
746-
jsonString := string(jsonTxBytes)
737+
jsonString := string(reply.Tx)
747738

748739
// contains the address in the right format
749740
require.Contains(jsonString, `"mintOutput":{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"]`)
@@ -784,9 +775,7 @@ func TestServiceGetTxJSON_OperationTxWithPropertyFxMintOp(t *testing.T) {
784775
}, &reply))
785776

786777
require.Equal(reply.Encoding, formatting.JSON)
787-
jsonTxBytes, err := stdjson.Marshal(reply.Tx)
788-
require.NoError(err)
789-
jsonString := string(jsonTxBytes)
778+
jsonString := string(reply.Tx)
790779

791780
// ensure memo is in hex
792781
require.Contains(jsonString, `"memo":"0x"`)
@@ -831,9 +820,7 @@ func TestServiceGetTxJSON_OperationTxWithPropertyFxMintOpMultiple(t *testing.T)
831820
}, &reply))
832821

833822
require.Equal(reply.Encoding, formatting.JSON)
834-
jsonTxBytes, err := stdjson.Marshal(reply.Tx)
835-
require.NoError(err)
836-
jsonString := string(jsonTxBytes)
823+
jsonString := string(reply.Tx)
837824

838825
// contains the address in the right format
839826
require.Contains(jsonString, `"mintOutput":{"addresses":["X-testing1lnk637g0edwnqc2tn8tel39652fswa3xk4r65e"]`)
@@ -2111,7 +2098,11 @@ func TestServiceGetBlock(t *testing.T) {
21112098
return
21122099
}
21132100
require.Equal(tt.encoding, reply.Encoding)
2114-
require.Equal(expected, reply.Block)
2101+
2102+
expectedJSON, err := stdjson.Marshal(expected)
2103+
require.NoError(err)
2104+
2105+
require.Equal(stdjson.RawMessage(expectedJSON), reply.Block)
21152106
})
21162107
}
21172108
}
@@ -2313,7 +2304,11 @@ func TestServiceGetBlockByHeight(t *testing.T) {
23132304
return
23142305
}
23152306
require.Equal(tt.encoding, reply.Encoding)
2316-
require.Equal(expected, reply.Block)
2307+
2308+
expectedJSON, err := stdjson.Marshal(expected)
2309+
require.NoError(err)
2310+
2311+
require.Equal(stdjson.RawMessage(expectedJSON), reply.Block)
23172312
})
23182313
}
23192314
}

vms/platformvm/service.go

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2142,7 +2142,6 @@ func (s *Service) IssueTx(_ *http.Request, args *api.FormattedTx, response *api.
21422142
return nil
21432143
}
21442144

2145-
// GetTx gets a tx
21462145
func (s *Service) GetTx(_ *http.Request, args *api.GetTxArgs, response *api.GetTxReply) error {
21472146
s.vm.ctx.Log.Debug("API called",
21482147
zap.String("service", "platform"),
@@ -2153,20 +2152,21 @@ func (s *Service) GetTx(_ *http.Request, args *api.GetTxArgs, response *api.GetT
21532152
if err != nil {
21542153
return fmt.Errorf("couldn't get tx: %w", err)
21552154
}
2156-
txBytes := tx.Bytes()
21572155
response.Encoding = args.Encoding
21582156

2157+
var result any
21592158
if args.Encoding == formatting.JSON {
21602159
tx.Unsigned.InitCtx(s.vm.ctx)
2161-
response.Tx = tx
2162-
return nil
2160+
result = tx
2161+
} else {
2162+
result, err = formatting.Encode(args.Encoding, tx.Bytes())
2163+
if err != nil {
2164+
return fmt.Errorf("couldn't encode tx as %s: %w", args.Encoding, err)
2165+
}
21632166
}
21642167

2165-
response.Tx, err = formatting.Encode(args.Encoding, txBytes)
2166-
if err != nil {
2167-
return fmt.Errorf("couldn't encode tx as %s: %w", args.Encoding, err)
2168-
}
2169-
return nil
2168+
response.Tx, err = stdjson.Marshal(result)
2169+
return err
21702170
}
21712171

21722172
type GetTxStatusArgs struct {
@@ -2638,18 +2638,19 @@ func (s *Service) GetBlock(_ *http.Request, args *api.GetBlockArgs, response *ap
26382638
}
26392639
response.Encoding = args.Encoding
26402640

2641+
var result any
26412642
if args.Encoding == formatting.JSON {
26422643
block.InitCtx(s.vm.ctx)
2643-
response.Block = block
2644-
return nil
2645-
}
2646-
2647-
response.Block, err = formatting.Encode(args.Encoding, block.Bytes())
2648-
if err != nil {
2649-
return fmt.Errorf("couldn't encode block %s as %s: %w", args.BlockID, args.Encoding, err)
2644+
result = block
2645+
} else {
2646+
result, err = formatting.Encode(args.Encoding, block.Bytes())
2647+
if err != nil {
2648+
return fmt.Errorf("couldn't encode block %s as %s: %w", args.BlockID, args.Encoding, err)
2649+
}
26502650
}
26512651

2652-
return nil
2652+
response.Block, err = stdjson.Marshal(result)
2653+
return err
26532654
}
26542655

26552656
// GetBlockByHeight returns the block at the given height.
@@ -2676,18 +2677,19 @@ func (s *Service) GetBlockByHeight(_ *http.Request, args *api.GetBlockByHeightAr
26762677
}
26772678
response.Encoding = args.Encoding
26782679

2680+
var result any
26792681
if args.Encoding == formatting.JSON {
26802682
block.InitCtx(s.vm.ctx)
2681-
response.Block = block
2682-
return nil
2683-
}
2684-
2685-
response.Block, err = formatting.Encode(args.Encoding, block.Bytes())
2686-
if err != nil {
2687-
return fmt.Errorf("couldn't encode block %s as %s: %w", blockID, args.Encoding, err)
2683+
result = block
2684+
} else {
2685+
result, err = formatting.Encode(args.Encoding, block.Bytes())
2686+
if err != nil {
2687+
return fmt.Errorf("couldn't encode block %s as %s: %w", blockID, args.Encoding, err)
2688+
}
26882689
}
26892690

2690-
return nil
2691+
response.Block, err = stdjson.Marshal(result)
2692+
return err
26912693
}
26922694

26932695
func (s *Service) getAPIUptime(staker *state.Staker) (*json.Float32, error) {

0 commit comments

Comments
 (0)