@@ -27,12 +27,21 @@ type Location struct {
2727}
2828
2929var (
30- ErrFailedToMarshal = errors .New ("failed to marshal location" )
31- ErrFailedToUnmarshal = errors .New ("failed to unmarshal location" )
30+ ErrFailedToMarshal = errors .New ("failed to marshal location" )
31+ ErrFailedToUnmarshal = errors .New ("failed to unmarshal location" )
32+ ErrLocationDataRequired = errors .New ("location data is required" )
3233)
3334
3435// marshalLocationData protojson-marshals data into l.Value and sets l.Type.
36+ // data must be a non-nil, populated message: an absent oneof value (Type set
37+ // but its corresponding Data variant not populated) is rejected rather than
38+ // silently written as an empty "{}" marker, which would otherwise reset
39+ // whatever cursor/progress this location represents.
3540func (l * Location ) marshalLocationData (typ string , data proto.Message ) error {
41+ if data == nil || ! data .ProtoReflect ().IsValid () {
42+ return fmt .Errorf ("%w: type %s" , ErrLocationDataRequired , typ )
43+ }
44+
3645 l .Type = typ
3746
3847 b , err := protojson .Marshal (data )
@@ -60,174 +69,35 @@ func (l *Location) Marshal(msg *xatu.CannonLocation) error {
6069
6170 switch msg .Type {
6271 case xatu .CannonType_BEACON_API_ETH_V2_BEACON_BLOCK_VOLUNTARY_EXIT :
63- l .Type = "BEACON_API_ETH_V2_BEACON_BLOCK_VOLUNTARY_EXIT"
64-
65- data := msg .GetEthV2BeaconBlockVoluntaryExit ()
66-
67- b , err := protojson .Marshal (data )
68- if err != nil {
69- return fmt .Errorf ("%w: %s" , ErrFailedToMarshal , err )
70- }
71-
72- l .Value = string (b )
72+ return l .marshalLocationData ("BEACON_API_ETH_V2_BEACON_BLOCK_VOLUNTARY_EXIT" , msg .GetEthV2BeaconBlockVoluntaryExit ())
7373 case xatu .CannonType_BEACON_API_ETH_V2_BEACON_BLOCK_PROPOSER_SLASHING :
74- l .Type = "BEACON_API_ETH_V2_BEACON_BLOCK_PROPOSER_SLASHING"
75-
76- data := msg .GetEthV2BeaconBlockProposerSlashing ()
77-
78- b , err := protojson .Marshal (data )
79- if err != nil {
80- return fmt .Errorf ("%w: %s" , ErrFailedToMarshal , err )
81- }
82-
83- l .Value = string (b )
74+ return l .marshalLocationData ("BEACON_API_ETH_V2_BEACON_BLOCK_PROPOSER_SLASHING" , msg .GetEthV2BeaconBlockProposerSlashing ())
8475 case xatu .CannonType_BEACON_API_ETH_V2_BEACON_BLOCK_DEPOSIT :
85- l .Type = "BEACON_API_ETH_V2_BEACON_BLOCK_DEPOSIT"
86-
87- data := msg .GetEthV2BeaconBlockDeposit ()
88-
89- b , err := protojson .Marshal (data )
90- if err != nil {
91- return fmt .Errorf ("%w: %s" , ErrFailedToMarshal , err )
92- }
93-
94- l .Value = string (b )
76+ return l .marshalLocationData ("BEACON_API_ETH_V2_BEACON_BLOCK_DEPOSIT" , msg .GetEthV2BeaconBlockDeposit ())
9577 case xatu .CannonType_BEACON_API_ETH_V2_BEACON_BLOCK_ATTESTER_SLASHING :
96- l .Type = "BEACON_API_ETH_V2_BEACON_BLOCK_ATTESTER_SLASHING"
97-
98- data := msg .GetEthV2BeaconBlockAttesterSlashing ()
99-
100- b , err := protojson .Marshal (data )
101- if err != nil {
102- return fmt .Errorf ("%w: %s" , ErrFailedToMarshal , err )
103- }
104-
105- l .Value = string (b )
106-
78+ return l .marshalLocationData ("BEACON_API_ETH_V2_BEACON_BLOCK_ATTESTER_SLASHING" , msg .GetEthV2BeaconBlockAttesterSlashing ())
10779 case xatu .CannonType_BEACON_API_ETH_V2_BEACON_BLOCK_EXECUTION_TRANSACTION :
108- l .Type = "BEACON_API_ETH_V2_BEACON_BLOCK_EXECUTION_TRANSACTION"
109-
110- data := msg .GetEthV2BeaconBlockExecutionTransaction ()
111-
112- b , err := protojson .Marshal (data )
113- if err != nil {
114- return fmt .Errorf ("%w: %s" , ErrFailedToMarshal , err )
115- }
116-
117- l .Value = string (b )
118-
80+ return l .marshalLocationData ("BEACON_API_ETH_V2_BEACON_BLOCK_EXECUTION_TRANSACTION" , msg .GetEthV2BeaconBlockExecutionTransaction ())
11981 case xatu .CannonType_BEACON_API_ETH_V2_BEACON_BLOCK_BLS_TO_EXECUTION_CHANGE :
120- l .Type = "BEACON_API_ETH_V2_BEACON_BLOCK_BLS_TO_EXECUTION_CHANGE"
121-
122- data := msg .GetEthV2BeaconBlockBlsToExecutionChange ()
123-
124- b , err := protojson .Marshal (data )
125- if err != nil {
126- return fmt .Errorf ("%w: %s" , ErrFailedToMarshal , err )
127- }
128-
129- l .Value = string (b )
82+ return l .marshalLocationData ("BEACON_API_ETH_V2_BEACON_BLOCK_BLS_TO_EXECUTION_CHANGE" , msg .GetEthV2BeaconBlockBlsToExecutionChange ())
13083 case xatu .CannonType_BEACON_API_ETH_V2_BEACON_BLOCK_WITHDRAWAL :
131- l .Type = "BEACON_API_ETH_V2_BEACON_BLOCK_WITHDRAWAL"
132-
133- data := msg .GetEthV2BeaconBlockWithdrawal ()
134-
135- b , err := protojson .Marshal (data )
136- if err != nil {
137- return fmt .Errorf ("%w: %s" , ErrFailedToMarshal , err )
138- }
139-
140- l .Value = string (b )
141-
84+ return l .marshalLocationData ("BEACON_API_ETH_V2_BEACON_BLOCK_WITHDRAWAL" , msg .GetEthV2BeaconBlockWithdrawal ())
14285 case xatu .CannonType_BEACON_API_ETH_V2_BEACON_BLOCK :
143- l .Type = "BEACON_API_ETH_V2_BEACON_BLOCK"
144-
145- data := msg .GetEthV2BeaconBlock ()
146-
147- b , err := protojson .Marshal (data )
148- if err != nil {
149- return fmt .Errorf ("%w: %s" , ErrFailedToMarshal , err )
150- }
151-
152- l .Value = string (b )
153-
86+ return l .marshalLocationData ("BEACON_API_ETH_V2_BEACON_BLOCK" , msg .GetEthV2BeaconBlock ())
15487 case xatu .CannonType_BEACON_API_ETH_V1_BEACON_BLOB_SIDECAR :
155- l .Type = "BEACON_API_ETH_V1_BEACON_BLOB_SIDECAR"
156-
157- data := msg .GetEthV1BeaconBlobSidecar ()
158-
159- b , err := protojson .Marshal (data )
160- if err != nil {
161- return fmt .Errorf ("%w: %s" , ErrFailedToMarshal , err )
162- }
163-
164- l .Value = string (b )
88+ return l .marshalLocationData ("BEACON_API_ETH_V1_BEACON_BLOB_SIDECAR" , msg .GetEthV1BeaconBlobSidecar ())
16589 case xatu .CannonType_BEACON_API_ETH_V1_PROPOSER_DUTY :
166- l .Type = "BEACON_API_ETH_V1_PROPOSER_DUTY"
167-
168- data := msg .GetEthV1BeaconProposerDuty ()
169-
170- b , err := protojson .Marshal (data )
171- if err != nil {
172- return fmt .Errorf ("%w: %s" , ErrFailedToMarshal , err )
173- }
174-
175- l .Value = string (b )
90+ return l .marshalLocationData ("BEACON_API_ETH_V1_PROPOSER_DUTY" , msg .GetEthV1BeaconProposerDuty ())
17691 case xatu .CannonType_BEACON_API_ETH_V2_BEACON_BLOCK_ELABORATED_ATTESTATION :
177- l .Type = "BEACON_API_ETH_V2_BEACON_BLOCK_ELABORATED_ATTESTATION"
178-
179- data := msg .GetEthV2BeaconBlockElaboratedAttestation ()
180-
181- b , err := protojson .Marshal (data )
182- if err != nil {
183- return fmt .Errorf ("%w: %s" , ErrFailedToMarshal , err )
184- }
185-
186- l .Value = string (b )
92+ return l .marshalLocationData ("BEACON_API_ETH_V2_BEACON_BLOCK_ELABORATED_ATTESTATION" , msg .GetEthV2BeaconBlockElaboratedAttestation ())
18793 case xatu .CannonType_BEACON_API_ETH_V1_BEACON_VALIDATORS :
188- l .Type = "BEACON_API_ETH_V1_BEACON_VALIDATORS"
189-
190- data := msg .GetEthV1BeaconValidators ()
191-
192- b , err := protojson .Marshal (data )
193- if err != nil {
194- return fmt .Errorf ("%w: %s" , ErrFailedToMarshal , err )
195- }
196-
197- l .Value = string (b )
94+ return l .marshalLocationData ("BEACON_API_ETH_V1_BEACON_VALIDATORS" , msg .GetEthV1BeaconValidators ())
19895 case xatu .CannonType_BEACON_API_ETH_V1_BEACON_COMMITTEE :
199- l .Type = "BEACON_API_ETH_V1_BEACON_COMMITTEE"
200-
201- data := msg .GetEthV1BeaconCommittee ()
202-
203- b , err := protojson .Marshal (data )
204- if err != nil {
205- return fmt .Errorf ("%w: %s" , ErrFailedToMarshal , err )
206- }
207-
208- l .Value = string (b )
96+ return l .marshalLocationData ("BEACON_API_ETH_V1_BEACON_COMMITTEE" , msg .GetEthV1BeaconCommittee ())
20997 case xatu .CannonType_BEACON_API_ETH_V1_BEACON_SYNC_COMMITTEE :
210- l .Type = "BEACON_API_ETH_V1_BEACON_SYNC_COMMITTEE"
211-
212- data := msg .GetEthV1BeaconSyncCommittee ()
213-
214- b , err := protojson .Marshal (data )
215- if err != nil {
216- return fmt .Errorf ("%w: %s" , ErrFailedToMarshal , err )
217- }
218-
219- l .Value = string (b )
98+ return l .marshalLocationData ("BEACON_API_ETH_V1_BEACON_SYNC_COMMITTEE" , msg .GetEthV1BeaconSyncCommittee ())
22099 case xatu .CannonType_BEACON_API_ETH_V2_BEACON_BLOCK_SYNC_AGGREGATE :
221- l .Type = "BEACON_API_ETH_V2_BEACON_BLOCK_SYNC_AGGREGATE"
222-
223- data := msg .GetEthV2BeaconBlockSyncAggregate ()
224-
225- b , err := protojson .Marshal (data )
226- if err != nil {
227- return fmt .Errorf ("%w: %s" , ErrFailedToMarshal , err )
228- }
229-
230- l .Value = string (b )
100+ return l .marshalLocationData ("BEACON_API_ETH_V2_BEACON_BLOCK_SYNC_AGGREGATE" , msg .GetEthV2BeaconBlockSyncAggregate ())
231101 case xatu .CannonType_BEACON_API_ETH_V2_BEACON_BLOCK_EXECUTION_REQUEST_DEPOSIT :
232102 return l .marshalLocationData ("BEACON_API_ETH_V2_BEACON_BLOCK_EXECUTION_REQUEST_DEPOSIT" , msg .GetEthV2BeaconBlockExecutionRequestDeposit ())
233103 case xatu .CannonType_BEACON_API_ETH_V2_BEACON_BLOCK_EXECUTION_REQUEST_WITHDRAWAL :
@@ -251,27 +121,9 @@ func (l *Location) Marshal(msg *xatu.CannonLocation) error {
251121 case xatu .CannonType_BEACON_API_ETH_V1_BEACON_STATE_PENDING_CONSOLIDATION :
252122 return l .marshalLocationData ("BEACON_API_ETH_V1_BEACON_STATE_PENDING_CONSOLIDATION" , msg .GetEthV1BeaconStatePendingConsolidation ())
253123 case xatu .CannonType_EXECUTION_CANONICAL_BLOCK :
254- l .Type = "EXECUTION_CANONICAL_BLOCK"
255-
256- data := msg .GetExecutionCanonicalBlock ()
257-
258- b , err := protojson .Marshal (data )
259- if err != nil {
260- return fmt .Errorf ("%w: %s" , ErrFailedToMarshal , err )
261- }
262-
263- l .Value = string (b )
124+ return l .marshalLocationData ("EXECUTION_CANONICAL_BLOCK" , msg .GetExecutionCanonicalBlock ())
264125 case xatu .CannonType_EXECUTION_CANONICAL_TRANSACTION :
265- l .Type = "EXECUTION_CANONICAL_TRANSACTION"
266-
267- data := msg .GetExecutionCanonicalTransaction ()
268-
269- b , err := protojson .Marshal (data )
270- if err != nil {
271- return fmt .Errorf ("%w: %s" , ErrFailedToMarshal , err )
272- }
273-
274- l .Value = string (b )
126+ return l .marshalLocationData ("EXECUTION_CANONICAL_TRANSACTION" , msg .GetExecutionCanonicalTransaction ())
275127 case xatu .CannonType_EXECUTION_CANONICAL_LOGS :
276128 return l .marshalLocationData ("EXECUTION_CANONICAL_LOGS" , msg .GetExecutionCanonicalLogs ())
277129 case xatu .CannonType_EXECUTION_CANONICAL_TRACES :
@@ -303,8 +155,6 @@ func (l *Location) Marshal(msg *xatu.CannonLocation) error {
303155 default :
304156 return fmt .Errorf ("unknown type: %s" , msg .Type )
305157 }
306-
307- return nil
308158}
309159
310160func (l * Location ) Unmarshal () (* xatu.CannonLocation , error ) {
0 commit comments