Skip to content

Commit 38d46db

Browse files
committed
handle error
1 parent bb16756 commit 38d46db

File tree

4 files changed

+90
-45
lines changed

4 files changed

+90
-45
lines changed

internal/espressoreader/espresso_reader.go

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,11 @@ func (e *EspressoReader) Run(ctx context.Context, ready chan<- struct{}) error {
132132
slog.Debug("Espresso:", "app", appAddress, "currentBlockHeight", currentEspressoBlockHeight)
133133

134134
var l1FinalizedTimestamp uint64
135-
lastProcessedL1Block, l1FinalizedTimestamp = e.readL1(ctx, app, currentEspressoBlockHeight, lastProcessedL1Block)
135+
lastProcessedL1Block, l1FinalizedTimestamp, err = e.readL1(ctx, app, currentEspressoBlockHeight, lastProcessedL1Block)
136+
if err != nil {
137+
slog.Error("failed reading L1", "error", err)
138+
continue
139+
}
136140
e.readEspresso(ctx, app, currentEspressoBlockHeight, namespace, lastProcessedL1Block, l1FinalizedTimestamp)
137141
}
138142
}
@@ -172,14 +176,19 @@ func (e *EspressoReader) bootstrap(ctx context.Context, app evmreader.TypeExport
172176
err = json.Unmarshal(nsTableBytes, &nsTables)
173177
if err != nil {
174178
slog.Error("failed fetching ns tables", "error", err, "ns table", nsTables)
179+
return err
175180
} else {
176181
for index, nsTable := range nsTables {
177182
nsTableBytes, _ := base64.StdEncoding.DecodeString(nsTable)
178183
ns := e.espressoHelper.extractNS(nsTableBytes)
179184
currentEspressoBlock := batchStartingBlock + uint64(index)
180185
if slices.Contains(ns, uint32(namespace)) {
181186
slog.Debug("found namespace contained in", "block", currentEspressoBlock)
182-
l1FinalizedHeight, l1FinalizedTimestamp = e.readL1(ctx, app, currentEspressoBlock, l1FinalizedHeight)
187+
l1FinalizedHeight, l1FinalizedTimestamp, err = e.readL1(ctx, app, currentEspressoBlock, l1FinalizedHeight)
188+
if err != nil {
189+
slog.Error("failed reading L1", "error", err)
190+
return err
191+
}
183192
e.readEspresso(ctx, app, currentEspressoBlock, namespace, l1FinalizedHeight, l1FinalizedTimestamp)
184193
} else {
185194
err = e.repository.UpdateLastProcessedEspressoBlock(ctx, app.IApplicationAddress, currentEspressoBlock)
@@ -197,7 +206,7 @@ func (e *EspressoReader) bootstrap(ctx context.Context, app evmreader.TypeExport
197206
return nil
198207
}
199208

200-
func (e *EspressoReader) readL1(ctx context.Context, app evmreader.TypeExportApplication, currentBlockHeight uint64, lastProcessedL1Block uint64) (uint64, uint64) {
209+
func (e *EspressoReader) readL1(ctx context.Context, app evmreader.TypeExportApplication, currentBlockHeight uint64, lastProcessedL1Block uint64) (uint64, uint64, error) {
201210
l1FinalizedLatestHeight, l1FinalizedTimestamp := e.espressoHelper.getL1FinalizedHeight(ctx, currentBlockHeight, e.maxDelay, e.url)
202211
// read L1 if there might be update
203212
if l1FinalizedLatestHeight > lastProcessedL1Block {
@@ -207,12 +216,16 @@ func (e *EspressoReader) readL1(ctx context.Context, app evmreader.TypeExportApp
207216
apps = append(apps, app) // make app into 1-element array
208217

209218
// start reading from the block after the prev height
210-
e.evmReader.ReadAndStoreInputs(ctx, lastProcessedL1Block, l1FinalizedLatestHeight, apps)
219+
err := e.evmReader.ReadAndStoreInputs(ctx, lastProcessedL1Block, l1FinalizedLatestHeight, apps)
220+
if err != nil {
221+
slog.Error("failed to read and store L1 inputs", "error", err)
222+
return 0, 0, err
223+
}
211224
// check for claim status and output execution
212225
// e.evmReader.CheckForClaimStatus(ctx, apps, l1FinalizedLatestHeight) // checked by the node
213226
// e.evmReader.CheckForOutputExecution(ctx, apps, l1FinalizedLatestHeight) // checked by the node
214227
}
215-
return l1FinalizedLatestHeight, l1FinalizedTimestamp
228+
return l1FinalizedLatestHeight, l1FinalizedTimestamp, nil
216229
}
217230

218231
type EspressoInput struct {
@@ -441,7 +454,7 @@ func (e *EspressoReader) readEspresso(ctx context.Context, appEvmType evmreader.
441454
)
442455
if err != nil {
443456
slog.Error("could not store Espresso input", "err", err)
444-
continue
457+
return
445458
}
446459

447460
// update nonce

internal/espressoreader/espresso_reader_unit_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -916,7 +916,7 @@ func (s *EspressoReaderUnitTestSuite) TestEdgeCaseSkippingL1Blocks() {
916916

917917
appContractAddress := common.HexToAddress("0x5a205fcb6947e200615b75c409ac0aa486d77649")
918918
indexValue := new(big.Int).SetUint64(1)
919-
inputData := []byte{0x01, 0x02, 0x03, 0x4a, 0x5b, 0x6c}
919+
inputData, _ := hex.DecodeString("6968957800000000000000000000000000000000000000000000000000000000000000010000000000000000000000001234567890abcdef1234567890abcdef12345678000000000000000000000000fedcba9876543210fedcba9876543210fedcba980000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000006322c8000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000008abcdef0123456789000000000000000000000000000000000000000000000000")
920920
rawLog := eth_types.Log{
921921
Address: common.HexToAddress("0x5a205fcb6947e200615b75c409ac0aa486d77649"),
922922
Topics: []common.Hash{common.HexToHash("0xabcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789")},

internal/espressoreader/espressoreader_service.go

Lines changed: 62 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -107,18 +107,24 @@ func (s *EspressoReaderService) requestNonce(w http.ResponseWriter, r *http.Requ
107107
w.Header().Set("Access-Control-Allow-Origin", "*")
108108
w.Header().Set("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers")
109109
if r.Method != http.MethodPost {
110+
w.WriteHeader(http.StatusMethodNotAllowed)
111+
json.NewEncoder(w).Encode(map[string]string{"error": "Only POST method is allowed"})
110112
return
111113
}
112114

113115
body, err := io.ReadAll(r.Body)
114116
if err != nil {
115-
slog.Error("could not read body", "err", err)
116-
// TODO: error?
117+
slog.Error("could not read request body", "error", err)
118+
http.Error(w, "Failed to read request body", http.StatusBadRequest)
119+
return
117120
}
121+
defer r.Body.Close()
122+
118123
nonceRequest := &NonceRequest{}
119124
if err := json.Unmarshal(body, nonceRequest); err != nil {
120-
slog.Error("could not unmarshal", "err", err)
121-
// ?
125+
slog.Error("could not unmarshal request body", "error", err, "body", string(body))
126+
http.Error(w, "Invalid request body", http.StatusBadRequest)
127+
return
122128
}
123129

124130
senderAddress := common.HexToAddress(nonceRequest.MsgSender)
@@ -128,9 +134,15 @@ func (s *EspressoReaderService) requestNonce(w http.ResponseWriter, r *http.Requ
128134
if nonceCache[applicationAddress] == nil {
129135
nonceCache[applicationAddress] = make(map[common.Address]uint64)
130136
}
131-
if nonceCache[applicationAddress][senderAddress] == 0 {
137+
_, exists := nonceCache[applicationAddress][senderAddress]
138+
if !exists {
132139
ctx := r.Context()
133-
nonce = s.queryNonceFromDb(ctx, senderAddress, applicationAddress)
140+
nonce, err = s.queryNonceFromDb(ctx, senderAddress, applicationAddress)
141+
if err != nil {
142+
slog.Error("failed to query nonce from database", "error", err, "senderAddress", senderAddress, "applicationAddress", applicationAddress)
143+
http.Error(w, "Failed to retrieve nonce", http.StatusInternalServerError)
144+
return
145+
}
134146
nonceCache[applicationAddress][senderAddress] = nonce
135147
} else {
136148
nonce = nonceCache[applicationAddress][senderAddress]
@@ -139,10 +151,6 @@ func (s *EspressoReaderService) requestNonce(w http.ResponseWriter, r *http.Requ
139151
slog.Debug("got nonce request", "senderAddress", senderAddress, "applicationAddress", applicationAddress)
140152

141153
nonceResponse := NonceResponse{Nonce: nonce}
142-
if err != nil {
143-
slog.Error("error json marshal nonce response", "err", err)
144-
// ?
145-
}
146154

147155
err = json.NewEncoder(w).Encode(nonceResponse)
148156
if err != nil {
@@ -156,14 +164,14 @@ func (s *EspressoReaderService) requestNonce(w http.ResponseWriter, r *http.Requ
156164
func (s *EspressoReaderService) queryNonceFromDb(
157165
ctx context.Context,
158166
senderAddress common.Address,
159-
applicationAddress common.Address) uint64 {
167+
applicationAddress common.Address) (uint64, error) {
160168
nonce, err := s.database.GetEspressoNonce(ctx, senderAddress.Hex(), applicationAddress.Hex())
161169
if err != nil {
162170
slog.Error("failed to get espresso nonce", "error", err)
163-
// TODO: error?
171+
return 0, err
164172
}
165173

166-
return nonce
174+
return nonce, nil
167175
}
168176

169177
type SubmitResponse struct {
@@ -175,20 +183,23 @@ func (s *EspressoReaderService) submit(w http.ResponseWriter, r *http.Request) {
175183
w.Header().Set("Access-Control-Allow-Origin", "*")
176184
w.Header().Set("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers")
177185
if r.Method != http.MethodPost {
178-
// TODO: error?
186+
w.WriteHeader(http.StatusMethodNotAllowed)
187+
json.NewEncoder(w).Encode(map[string]string{"error": "Only POST method is allowed"})
179188
return
180189
}
181190

182191
body, err := io.ReadAll(r.Body)
183192
if err != nil {
184-
slog.Error("could not read body", "err", err)
193+
slog.Error("could not read request body", "error", err)
194+
http.Error(w, "Failed to read request body", http.StatusBadRequest)
195+
return
185196
}
186197
slog.Debug("got submit request", "request body", string(body))
187198

188199
msgSender, typedData, sigHash, err := ExtractSigAndData(string(body))
189200
if err != nil {
190201
slog.Error("transaction not correctly formatted", "error", err)
191-
// TODO: error?
202+
http.Error(w, "Invalid transaction format", http.StatusBadRequest)
192203
return
193204
}
194205
submitResponse := SubmitResponse{Id: sigHash}
@@ -198,43 +209,62 @@ func (s *EspressoReaderService) submit(w http.ResponseWriter, r *http.Request) {
198209
client := client.NewClient(s.EspressoBaseUrl)
199210
ctx := r.Context()
200211
_, namespace, err := getEspressoConfig(ctx, appAddress, s.database, s.blockchainHttpEndpoint)
212+
if err != nil {
213+
slog.Error("failed to get espresso config", "error", err, "appAddress", appAddress)
214+
http.Error(w, "Failed to get application configuration", http.StatusInternalServerError)
215+
return
216+
}
201217
var tx types.Transaction
202218
tx.Namespace = namespace
203219
tx.Payload = body
204220
_, err = client.SubmitTransaction(ctx, tx)
205221
if err != nil {
206-
slog.Error("espresso tx submit error", "err", err)
207-
// TODO: error?
222+
slog.Error("espresso tx submit error", "error", err)
223+
http.Error(w, "Failed to submit transaction to Espresso", http.StatusInternalServerError)
208224
return
209225
}
210226

211-
err = json.NewEncoder(w).Encode(submitResponse)
212-
if err != nil {
213-
slog.Info("Internal server error",
214-
"service", "espresso submit endpoint",
215-
"err", err)
216-
http.Error(w, err.Error(), http.StatusInternalServerError)
217-
// TODO: error?
227+
if err := json.NewEncoder(w).Encode(submitResponse); err != nil {
228+
slog.Error("failed to encode submit response", "error", err, "submitResponse", submitResponse)
229+
http.Error(w, "Internal server error", http.StatusInternalServerError)
218230
return
219231
}
220232

221233
// update nonce cache
222234
if nonceCache[appAddress] == nil {
223-
slog.Error("Should query nonce before submit")
224-
// TODO: error?
235+
slog.Error("Should query nonce before submit", "appAddress", appAddress)
236+
http.Error(w, "Nonce not initialized for this application. Please request a nonce first.", http.StatusBadRequest)
237+
return
238+
}
239+
nonceInRequestFloat, ok := typedData.Message["nonce"].(float64)
240+
if !ok {
241+
slog.Error("Nonce not found or invalid type in request", "typedData", typedData)
242+
http.Error(w, "Invalid or missing nonce in request", http.StatusBadRequest)
225243
return
226244
}
227-
nonceInRequest := uint64(typedData.Message["nonce"].(float64))
228-
if nonceCache[appAddress][msgSender] == 0 {
245+
nonceInRequest := uint64(nonceInRequestFloat)
246+
247+
cachedNonce, exists := nonceCache[appAddress][msgSender]
248+
if !exists {
229249
ctx := r.Context()
230-
nonceInDb := s.queryNonceFromDb(ctx, msgSender, appAddress)
250+
nonceInDb, err := s.queryNonceFromDb(ctx, msgSender, appAddress)
251+
if err != nil {
252+
slog.Error("failed to query nonce from database during submit", "error", err, "senderAddress", msgSender, "applicationAddress", appAddress)
253+
http.Error(w, "Failed to retrieve nonce for validation", http.StatusInternalServerError)
254+
return
255+
}
231256
if nonceInRequest != nonceInDb {
232-
slog.Error("Nonce in request is incorrect")
233-
// TODO: error?
257+
slog.Error("Nonce in request is incorrect", "nonceInRequest", nonceInRequest, "nonceInDb", nonceInDb, "senderAddress", msgSender, "applicationAddress", appAddress)
258+
http.Error(w, "Incorrect nonce", http.StatusBadRequest)
234259
return
235260
}
236261
nonceCache[appAddress][msgSender] = nonceInDb + 1
237262
} else {
263+
if nonceInRequest != cachedNonce {
264+
slog.Error("Nonce in request is incorrect", "requestNonce", nonceInRequest, "cachedNonce", cachedNonce, "senderAddress", msgSender, "applicationAddress", appAddress)
265+
http.Error(w, "Incorrect nonce", http.StatusBadRequest)
266+
return
267+
}
238268
nonceCache[appAddress][msgSender]++
239269
}
240270
}

internal/evmreader/input.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -153,19 +153,23 @@ func (r *EvmReader) ReadAndStoreInputs(
153153
combinedIndex, err := r.repository.GetInputIndexWithTx(ctx, dbTx, address.Hex())
154154
if err != nil {
155155
slog.Error("evmreader: failed to read index", "app", address, "error", err)
156+
return errors.New("evmreader: failed to read index")
156157
}
157158
if combinedIndex != input.Index && r.shouldModifyIndex == true {
158159
slog.Info("evmreader: Overriding input index", "onchain-index", input.Index, "new-index", combinedIndex)
159160
input.Index = combinedIndex
160161
modifiedRawData, err := r.modifyIndexInRaw(input.RawData, combinedIndex)
161-
if err == nil {
162-
input.RawData = modifiedRawData
162+
if err != nil {
163+
slog.Error("evmreader: failed to modify index", "app", address, "error", err)
164+
return errors.New("evmreader: failed to modify index")
163165
}
166+
input.RawData = modifiedRawData
164167
}
165168
// update input index
166169
err = r.repository.UpdateInputIndexWithTx(ctx, dbTx, address.Hex())
167170
if err != nil {
168171
slog.Error("failed to update index", "app", address, "error", err)
172+
return errors.New("evmreader: failed to update index")
169173
}
170174
epochInputMap[currentEpoch] = append(currentInputs, input)
171175

@@ -201,15 +205,13 @@ func (r *EvmReader) ReadAndStoreInputs(
201205
"address", address,
202206
"error", err,
203207
)
204-
dbTx.Rollback(ctx)
205-
continue
208+
return errors.New("evmreader: Error storing inputs and epochs")
206209
}
207210
// Commit transaction
208211
err = dbTx.Commit(ctx)
209212
if err != nil {
210213
slog.Error("could not commit db tx", "err", err)
211-
dbTx.Rollback(ctx)
212-
continue
214+
return errors.New("evmreader: could not commit db tx")
213215
}
214216

215217
// Store everything

0 commit comments

Comments
 (0)