Skip to content

Commit 39d2e77

Browse files
committed
Add err handling in proto helper
1 parent b52b8c1 commit 39d2e77

3 files changed

Lines changed: 132 additions & 40 deletions

File tree

pkg/chains/stellar/proto_helpers.go

Lines changed: 98 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,19 @@ package stellar
33
import (
44
"encoding/base64"
55
"encoding/hex"
6+
"errors"
67
"fmt"
78

89
"github.com/smartcontractkit/chainlink-common/pkg/types/chains/stellar"
910
)
1011

1112
// xdrToBytes base64-decodes a domain XDR string to raw binary.
12-
// Invalid base64 returns nil silently; malformed XDR should not reach ToProto.
13-
func xdrToBytes(x stellar.XDR) []byte {
14-
b, _ := base64.StdEncoding.DecodeString(string(x))
15-
return b
13+
func xdrToBytes(x stellar.XDR) ([]byte, error) {
14+
b, err := base64.StdEncoding.DecodeString(string(x))
15+
if err != nil {
16+
return nil, fmt.Errorf("invalid base64 XDR %q: %w", x, err)
17+
}
18+
return b, nil
1619
}
1720

1821
// bytesToXDR base64-encodes raw binary XDR to the domain type.
@@ -21,10 +24,12 @@ func bytesToXDR(b []byte) stellar.XDR {
2124
}
2225

2326
// hashToBytes hex-decodes a domain hash string to raw bytes.
24-
// Returns nil on invalid hex; should not happen for well-formed hashes.
25-
func hashToBytes(h string) []byte {
26-
b, _ := hex.DecodeString(h)
27-
return b
27+
func hashToBytes(h string) ([]byte, error) {
28+
b, err := hex.DecodeString(h)
29+
if err != nil {
30+
return nil, fmt.Errorf("invalid hex hash %q: %w", h, err)
31+
}
32+
return b, nil
2833
}
2934

3035
// bytesToHash hex-encodes raw hash bytes to a string.
@@ -35,12 +40,21 @@ func bytesToHash(b []byte) string {
3540
// ---- GetLedgerEntries ----
3641

3742
// ConvertGetLedgerEntriesRequestToProto converts a domain GetLedgerEntriesRequest to its proto representation.
38-
func ConvertGetLedgerEntriesRequestToProto(req stellar.GetLedgerEntriesRequest) *GetLedgerEntriesRequest {
43+
func ConvertGetLedgerEntriesRequestToProto(req stellar.GetLedgerEntriesRequest) (*GetLedgerEntriesRequest, error) {
3944
keys := make([][]byte, len(req.Keys))
45+
var errs []error
4046
for i, k := range req.Keys {
41-
keys[i] = xdrToBytes(k)
47+
b, err := xdrToBytes(k)
48+
if err != nil {
49+
errs = append(errs, fmt.Errorf("key[%d]: %w", i, err))
50+
continue
51+
}
52+
keys[i] = b
53+
}
54+
if len(errs) > 0 {
55+
return nil, errors.Join(errs...)
4256
}
43-
return &GetLedgerEntriesRequest{Keys: keys}
57+
return &GetLedgerEntriesRequest{Keys: keys}, nil
4458
}
4559

4660
// ConvertGetLedgerEntriesRequestFromProto converts a proto GetLedgerEntriesRequest to the domain type.
@@ -60,22 +74,37 @@ func ConvertGetLedgerEntriesRequestFromProto(p *GetLedgerEntriesRequest) (stella
6074
}
6175

6276
// ConvertLedgerEntryResultToProto converts a domain LedgerEntryResult to its proto representation.
63-
func ConvertLedgerEntryResultToProto(r stellar.LedgerEntryResult) *LedgerEntryResult {
77+
func ConvertLedgerEntryResultToProto(r stellar.LedgerEntryResult) (*LedgerEntryResult, error) {
78+
keyXDR, err := xdrToBytes(r.KeyXDR)
79+
if err != nil {
80+
return nil, fmt.Errorf("key_xdr: %w", err)
81+
}
82+
dataXDR, err := xdrToBytes(r.DataXDR)
83+
if err != nil {
84+
return nil, fmt.Errorf("data_xdr: %w", err)
85+
}
86+
extXDR, err := xdrToBytes(r.ExtensionXDR)
87+
if err != nil {
88+
return nil, fmt.Errorf("extension_xdr: %w", err)
89+
}
6490
pr := &LedgerEntryResult{
65-
KeyXdr: xdrToBytes(r.KeyXDR),
66-
DataXdr: xdrToBytes(r.DataXDR),
91+
KeyXdr: keyXDR,
92+
DataXdr: dataXDR,
6793
LastModifiedLedger: r.LastModifiedLedger,
68-
ExtensionXdr: xdrToBytes(r.ExtensionXDR),
94+
ExtensionXdr: extXDR,
6995
}
7096
if r.LiveUntilLedgerSeq != nil {
7197
pr.HasLiveUntilLedgerSeq = true
7298
pr.LiveUntilLedgerSeq = *r.LiveUntilLedgerSeq
7399
}
74-
return pr
100+
return pr, nil
75101
}
76102

77103
// ConvertLedgerEntryResultFromProto converts a proto LedgerEntryResult to the domain type.
78-
func ConvertLedgerEntryResultFromProto(p *LedgerEntryResult) stellar.LedgerEntryResult {
104+
func ConvertLedgerEntryResultFromProto(p *LedgerEntryResult) (stellar.LedgerEntryResult, error) {
105+
if p == nil {
106+
return stellar.LedgerEntryResult{}, fmt.Errorf("ledger entry result is nil")
107+
}
79108
r := stellar.LedgerEntryResult{
80109
KeyXDR: bytesToXDR(p.GetKeyXdr()),
81110
DataXDR: bytesToXDR(p.GetDataXdr()),
@@ -86,55 +115,91 @@ func ConvertLedgerEntryResultFromProto(p *LedgerEntryResult) stellar.LedgerEntry
86115
v := p.GetLiveUntilLedgerSeq()
87116
r.LiveUntilLedgerSeq = &v
88117
}
89-
return r
118+
return r, nil
90119
}
91120

92121
// ConvertGetLedgerEntriesResponseToProto converts a domain GetLedgerEntriesResponse to its proto representation.
93-
func ConvertGetLedgerEntriesResponseToProto(resp stellar.GetLedgerEntriesResponse) *GetLedgerEntriesResponse {
122+
func ConvertGetLedgerEntriesResponseToProto(resp stellar.GetLedgerEntriesResponse) (*GetLedgerEntriesResponse, error) {
94123
entries := make([]*LedgerEntryResult, 0, len(resp.Entries))
95-
for _, e := range resp.Entries {
96-
entries = append(entries, ConvertLedgerEntryResultToProto(e))
124+
var errs []error
125+
for i, e := range resp.Entries {
126+
protoEntry, err := ConvertLedgerEntryResultToProto(e)
127+
if err != nil {
128+
errs = append(errs, fmt.Errorf("entry[%d]: %w", i, err))
129+
continue
130+
}
131+
entries = append(entries, protoEntry)
132+
}
133+
if len(errs) > 0 {
134+
return nil, errors.Join(errs...)
97135
}
98136
return &GetLedgerEntriesResponse{
99137
Entries: entries,
100138
LatestLedger: resp.LatestLedger,
101-
}
139+
}, nil
102140
}
103141

104142
// ConvertGetLedgerEntriesResponseFromProto converts a proto GetLedgerEntriesResponse to the domain type.
105-
func ConvertGetLedgerEntriesResponseFromProto(p *GetLedgerEntriesResponse) stellar.GetLedgerEntriesResponse {
143+
func ConvertGetLedgerEntriesResponseFromProto(p *GetLedgerEntriesResponse) (stellar.GetLedgerEntriesResponse, error) {
144+
if p == nil {
145+
return stellar.GetLedgerEntriesResponse{}, fmt.Errorf("get ledger entries response is nil")
146+
}
106147
entries := make([]stellar.LedgerEntryResult, 0, len(p.GetEntries()))
107-
for _, pe := range p.GetEntries() {
108-
entries = append(entries, ConvertLedgerEntryResultFromProto(pe))
148+
var errs []error
149+
for i, pe := range p.GetEntries() {
150+
e, err := ConvertLedgerEntryResultFromProto(pe)
151+
if err != nil {
152+
errs = append(errs, fmt.Errorf("entry[%d]: %w", i, err))
153+
continue
154+
}
155+
entries = append(entries, e)
156+
}
157+
if len(errs) > 0 {
158+
return stellar.GetLedgerEntriesResponse{}, errors.Join(errs...)
109159
}
110160
return stellar.GetLedgerEntriesResponse{
111161
Entries: entries,
112162
LatestLedger: p.GetLatestLedger(),
113-
}
163+
}, nil
114164
}
115165

116166
// ---- GetLatestLedger ----
117167

118168
// ConvertGetLatestLedgerResponseToProto converts a domain GetLatestLedgerResponse to its proto representation.
119-
func ConvertGetLatestLedgerResponseToProto(resp stellar.GetLatestLedgerResponse) *GetLatestLedgerResponse {
169+
func ConvertGetLatestLedgerResponseToProto(resp stellar.GetLatestLedgerResponse) (*GetLatestLedgerResponse, error) {
170+
hash, err := hashToBytes(string(resp.Hash))
171+
if err != nil {
172+
return nil, fmt.Errorf("hash: %w", err)
173+
}
174+
headerXDR, err := xdrToBytes(resp.LedgerHeaderXDR)
175+
if err != nil {
176+
return nil, fmt.Errorf("ledger_header_xdr: %w", err)
177+
}
178+
metaXDR, err := xdrToBytes(resp.LedgerMetadataXDR)
179+
if err != nil {
180+
return nil, fmt.Errorf("ledger_metadata_xdr: %w", err)
181+
}
120182
return &GetLatestLedgerResponse{
121-
Hash: hashToBytes(string(resp.Hash)),
183+
Hash: hash,
122184
ProtocolVersion: resp.ProtocolVersion,
123185
Sequence: resp.Sequence,
124186
LedgerCloseTime: resp.LedgerCloseTime,
125-
LedgerHeaderXdr: xdrToBytes(resp.LedgerHeaderXDR),
126-
LedgerMetadataXdr: xdrToBytes(resp.LedgerMetadataXDR),
127-
}
187+
LedgerHeaderXdr: headerXDR,
188+
LedgerMetadataXdr: metaXDR,
189+
}, nil
128190
}
129191

130192
// ConvertGetLatestLedgerResponseFromProto converts a proto GetLatestLedgerResponse to the domain type.
131-
func ConvertGetLatestLedgerResponseFromProto(p *GetLatestLedgerResponse) stellar.GetLatestLedgerResponse {
193+
func ConvertGetLatestLedgerResponseFromProto(p *GetLatestLedgerResponse) (stellar.GetLatestLedgerResponse, error) {
194+
if p == nil {
195+
return stellar.GetLatestLedgerResponse{}, fmt.Errorf("get latest ledger response is nil")
196+
}
132197
return stellar.GetLatestLedgerResponse{
133198
Hash: stellar.LedgerHash(bytesToHash(p.GetHash())),
134199
ProtocolVersion: p.GetProtocolVersion(),
135200
Sequence: p.GetSequence(),
136201
LedgerCloseTime: p.GetLedgerCloseTime(),
137202
LedgerHeaderXDR: bytesToXDR(p.GetLedgerHeaderXdr()),
138203
LedgerMetadataXDR: bytesToXDR(p.GetLedgerMetadataXdr()),
139-
}
204+
}, nil
140205
}

pkg/loop/internal/relayer/stellar.go

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,31 @@ func NewStellarClient(client stelpb.StellarClient) *StellarClient {
2525
}
2626

2727
func (sc *StellarClient) GetLedgerEntries(ctx context.Context, req stellar.GetLedgerEntriesRequest) (stellar.GetLedgerEntriesResponse, error) {
28-
pReq := stelpb.ConvertGetLedgerEntriesRequestToProto(req)
28+
pReq, err := stelpb.ConvertGetLedgerEntriesRequestToProto(req)
29+
if err != nil {
30+
return stellar.GetLedgerEntriesResponse{}, fmt.Errorf("invalid GetLedgerEntries request: %w", err)
31+
}
2932
pResp, err := sc.grpcClient.GetLedgerEntries(ctx, pReq)
3033
if err != nil {
3134
return stellar.GetLedgerEntriesResponse{}, net.WrapRPCErr(err)
3235
}
33-
return stelpb.ConvertGetLedgerEntriesResponseFromProto(pResp), nil
36+
resp, err := stelpb.ConvertGetLedgerEntriesResponseFromProto(pResp)
37+
if err != nil {
38+
return stellar.GetLedgerEntriesResponse{}, fmt.Errorf("invalid GetLedgerEntries response: %w", err)
39+
}
40+
return resp, nil
3441
}
3542

3643
func (sc *StellarClient) GetLatestLedger(ctx context.Context) (stellar.GetLatestLedgerResponse, error) {
3744
pResp, err := sc.grpcClient.GetLatestLedger(ctx, &emptypb.Empty{})
3845
if err != nil {
3946
return stellar.GetLatestLedgerResponse{}, net.WrapRPCErr(err)
4047
}
41-
return stelpb.ConvertGetLatestLedgerResponseFromProto(pResp), nil
48+
resp, err := stelpb.ConvertGetLatestLedgerResponseFromProto(pResp)
49+
if err != nil {
50+
return stellar.GetLatestLedgerResponse{}, fmt.Errorf("invalid GetLatestLedger response: %w", err)
51+
}
52+
return resp, nil
4253
}
4354

4455
// stellarServer wraps types.StellarService and exposes it as a stelpb.StellarServer gRPC endpoint.
@@ -65,13 +76,21 @@ func (s *stellarServer) GetLedgerEntries(ctx context.Context, req *stelpb.GetLed
6576
if err != nil {
6677
return nil, net.WrapRPCErr(err)
6778
}
68-
return stelpb.ConvertGetLedgerEntriesResponseToProto(dResp), nil
79+
pResp, err := stelpb.ConvertGetLedgerEntriesResponseToProto(dResp)
80+
if err != nil {
81+
return nil, fmt.Errorf("invalid GetLedgerEntries response: %w", err)
82+
}
83+
return pResp, nil
6984
}
7085

7186
func (s *stellarServer) GetLatestLedger(ctx context.Context, _ *emptypb.Empty) (*stelpb.GetLatestLedgerResponse, error) {
7287
dResp, err := s.impl.GetLatestLedger(ctx)
7388
if err != nil {
7489
return nil, net.WrapRPCErr(err)
7590
}
76-
return stelpb.ConvertGetLatestLedgerResponseToProto(dResp), nil
91+
pResp, err := stelpb.ConvertGetLatestLedgerResponseToProto(dResp)
92+
if err != nil {
93+
return nil, fmt.Errorf("invalid GetLatestLedger response: %w", err)
94+
}
95+
return pResp, nil
7796
}

pkg/loop/internal/relayerset/stellar.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@ func (ss *stellarServer) GetLedgerEntries(ctx context.Context, req *stelpb.GetLe
5050
if err != nil {
5151
return nil, net.WrapRPCErr(err)
5252
}
53-
return stelpb.ConvertGetLedgerEntriesResponseToProto(dResp), nil
53+
pResp, err := stelpb.ConvertGetLedgerEntriesResponseToProto(dResp)
54+
if err != nil {
55+
return nil, fmt.Errorf("invalid GetLedgerEntries response: %w", err)
56+
}
57+
return pResp, nil
5458
}
5559

5660
func (ss *stellarServer) GetLatestLedger(ctx context.Context, _ *emptypb.Empty) (*stelpb.GetLatestLedgerResponse, error) {
@@ -62,7 +66,11 @@ func (ss *stellarServer) GetLatestLedger(ctx context.Context, _ *emptypb.Empty)
6266
if err != nil {
6367
return nil, net.WrapRPCErr(err)
6468
}
65-
return stelpb.ConvertGetLatestLedgerResponseToProto(dResp), nil
69+
pResp, err := stelpb.ConvertGetLatestLedgerResponseToProto(dResp)
70+
if err != nil {
71+
return nil, fmt.Errorf("invalid GetLatestLedger response: %w", err)
72+
}
73+
return pResp, nil
6674
}
6775

6876
// getStellarService extracts the RelayID from context metadata and returns the StellarService

0 commit comments

Comments
 (0)