-
Notifications
You must be signed in to change notification settings - Fork 264
Expand file tree
/
Copy pathda.go
More file actions
191 lines (178 loc) · 6.06 KB
/
da.go
File metadata and controls
191 lines (178 loc) · 6.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
package types
import (
"context"
"errors"
"fmt"
"strings"
"github.com/rs/zerolog"
coreda "github.com/evstack/ev-node/core/da"
)
// SubmitWithHelpers performs blob submission using the underlying DA layer,
// handling error mapping to produce a ResultSubmit.
// It assumes blob size filtering is handled within the DA implementation's Submit.
// It mimics the logic previously found in da.DAClient.Submit.
func SubmitWithHelpers(
ctx context.Context,
da coreda.DA, // Use the core DA interface
logger zerolog.Logger,
data [][]byte,
gasPrice float64,
namespace []byte, // New namespace parameter
options []byte,
) coreda.ResultSubmit { // Return core ResultSubmit type
ids, err := da.SubmitWithOptions(ctx, data, gasPrice, namespace, options)
// Handle errors returned by Submit
if err != nil {
if errors.Is(err, context.Canceled) {
logger.Debug().Msg("DA submission canceled via helper due to context cancellation")
return coreda.ResultSubmit{
BaseResult: coreda.BaseResult{
Code: coreda.StatusContextCanceled,
Message: "submission canceled",
IDs: ids,
},
}
}
status := coreda.StatusError
switch {
case errors.Is(err, coreda.ErrTxTimedOut):
status = coreda.StatusNotIncludedInBlock
case errors.Is(err, coreda.ErrTxAlreadyInMempool):
status = coreda.StatusAlreadyInMempool
case errors.Is(err, coreda.ErrTxIncorrectAccountSequence):
status = coreda.StatusIncorrectAccountSequence
case errors.Is(err, coreda.ErrBlobSizeOverLimit):
status = coreda.StatusTooBig
case errors.Is(err, coreda.ErrContextDeadline):
status = coreda.StatusContextDeadline
}
// Use debug level for StatusTooBig as it gets handled later in submitToDA through recursive splitting
if status == coreda.StatusTooBig {
logger.Debug().Err(err).Uint64("status", uint64(status)).Msg("DA submission failed via helper")
} else {
logger.Error().Err(err).Uint64("status", uint64(status)).Msg("DA submission failed via helper")
}
return coreda.ResultSubmit{
BaseResult: coreda.BaseResult{
Code: status,
Message: "failed to submit blobs: " + err.Error(),
IDs: ids,
SubmittedCount: uint64(len(ids)),
Height: 0,
},
}
}
if len(ids) == 0 && len(data) > 0 {
logger.Warn().Msg("DA submission via helper returned no IDs for non-empty input data")
return coreda.ResultSubmit{
BaseResult: coreda.BaseResult{
Code: coreda.StatusError,
Message: "failed to submit blobs: no IDs returned despite non-empty input",
},
}
}
// Get height from the first ID
var height uint64
if len(ids) > 0 {
height, _, err = coreda.SplitID(ids[0])
if err != nil {
logger.Error().Err(err).Msg("failed to split ID")
}
}
logger.Debug().Int("num_ids", len(ids)).Msg("DA submission successful via helper")
return coreda.ResultSubmit{
BaseResult: coreda.BaseResult{
Code: coreda.StatusSuccess,
IDs: ids,
SubmittedCount: uint64(len(ids)),
Height: height,
BlobSize: 0,
},
}
}
// RetrieveWithHelpers performs blob retrieval using the underlying DA layer,
// handling error mapping to produce a ResultRetrieve.
// It mimics the logic previously found in da.DAClient.Retrieve.
func RetrieveWithHelpers(
ctx context.Context,
da coreda.DA,
logger zerolog.Logger,
dataLayerHeight uint64,
namespace []byte,
) coreda.ResultRetrieve {
// 1. Get IDs
idsResult, err := da.GetIDs(ctx, dataLayerHeight, namespace)
if err != nil {
// Handle specific "not found" error
if strings.Contains(err.Error(), coreda.ErrBlobNotFound.Error()) {
logger.Debug().Uint64("height", dataLayerHeight).Msg("Retrieve helper: Blobs not found at height")
return coreda.ResultRetrieve{
BaseResult: coreda.BaseResult{
Code: coreda.StatusNotFound,
Message: coreda.ErrBlobNotFound.Error(),
Height: dataLayerHeight,
},
}
}
if strings.Contains(err.Error(), coreda.ErrHeightFromFuture.Error()) {
logger.Debug().Uint64("height", dataLayerHeight).Msg("Retrieve helper: Blobs not found at height")
return coreda.ResultRetrieve{
BaseResult: coreda.BaseResult{
Code: coreda.StatusHeightFromFuture,
Message: coreda.ErrHeightFromFuture.Error(),
Height: dataLayerHeight,
},
}
}
// Handle other errors during GetIDs
logger.Error().Uint64("height", dataLayerHeight).Err(err).Msg("Retrieve helper: Failed to get IDs")
return coreda.ResultRetrieve{
BaseResult: coreda.BaseResult{
Code: coreda.StatusError,
Message: fmt.Sprintf("failed to get IDs: %s", err.Error()),
Height: dataLayerHeight,
},
}
}
// This check should technically be redundant if GetIDs correctly returns ErrBlobNotFound
if idsResult == nil || len(idsResult.IDs) == 0 {
logger.Debug().Uint64("height", dataLayerHeight).Msg("Retrieve helper: No IDs found at height")
return coreda.ResultRetrieve{
BaseResult: coreda.BaseResult{
Code: coreda.StatusNotFound,
Message: coreda.ErrBlobNotFound.Error(),
Height: dataLayerHeight,
},
}
}
// 2. Get Blobs using the retrieved IDs in batches
batchSize := 100
blobs := make([][]byte, 0, len(idsResult.IDs))
for i := 0; i < len(idsResult.IDs); i += batchSize {
end := min(i+batchSize, len(idsResult.IDs))
batchBlobs, err := da.Get(ctx, idsResult.IDs[i:end], namespace)
if err != nil {
// Handle errors during Get
logger.Error().Uint64("height", dataLayerHeight).Int("num_ids", len(idsResult.IDs)).Err(err).Msg("Retrieve helper: Failed to get blobs")
return coreda.ResultRetrieve{
BaseResult: coreda.BaseResult{
Code: coreda.StatusError,
Message: fmt.Sprintf("failed to get blobs for batch %d-%d: %s", i, end-1, err.Error()),
Height: dataLayerHeight,
},
}
}
blobs = append(blobs, batchBlobs...)
}
// Success
logger.Debug().Uint64("height", dataLayerHeight).Int("num_blobs", len(blobs)).Msg("Retrieve helper: Successfully retrieved blobs")
return coreda.ResultRetrieve{
BaseResult: coreda.BaseResult{
Code: coreda.StatusSuccess,
Height: dataLayerHeight,
IDs: idsResult.IDs,
Timestamp: idsResult.Timestamp,
},
Data: blobs,
}
}