Skip to content

Commit 3818570

Browse files
Scheduled Transactions indexing (#95)
* enable reading events from system collection * add to slow path (when GetTransactionResultsByBlockID has failed) * fix for final system transaction * Update state/process.go Co-authored-by: Jordan Schalm <jordan@dapperlabs.com> * update context cancellation handling on slow path * minor fix stop entirely when system collection is shorter than the expected length * retrieve transaction infos for system collection on slow path * use defer to end the tracing span * check grpc status code for cancellation --------- Co-authored-by: Jordan Schalm <jordan@dapperlabs.com>
1 parent a94ac8e commit 3818570

1 file changed

Lines changed: 79 additions & 41 deletions

File tree

state/process.go

Lines changed: 79 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ func (i *Indexer) processBlock(rctx context.Context, spork *config.Spork, height
4141
slowPath := false
4242
unsealed := false
4343
var span trace.Span
44+
defer func() { span.End() }()
4445
outer:
4546
for {
4647
if span != nil {
@@ -127,64 +128,55 @@ outer:
127128
for _, col := range block.CollectionGuarantees {
128129
colData := &collectionData{}
129130
cols = append(cols, colData)
130-
initialCol := true
131131
for {
132-
select {
133-
case <-ctx.Done():
134-
span.End()
135-
return
136-
default:
137-
}
138-
if initialCol {
139-
initialCol = false
140-
} else {
141-
time.Sleep(time.Second)
142-
}
143132
client := spork.AccessNodes.Client()
144133
info, err := client.CollectionByID(ctx, col.CollectionId)
145134
if err != nil {
146135
log.Errorf(
147136
"Failed to fetch collection %x in block %x at height %d: %s",
148137
col.CollectionId, hash, height, err,
149138
)
139+
if status.Code(err) == codes.Canceled {
140+
return
141+
}
142+
time.Sleep(time.Second)
150143
continue
151144
}
152145
tctx := ctx
153146
for _, txnHash := range info.TransactionIds {
154147
ctx = tctx
155-
initialTxn := true
156148
txnIndex++
157149
for {
158-
select {
159-
case <-ctx.Done():
160-
span.End()
161-
return
162-
default:
163-
}
164-
if initialTxn {
165-
initialTxn = false
166-
} else {
167-
time.Sleep(time.Second)
168-
}
169150
client := spork.AccessNodes.Client()
170151
info, err := client.Transaction(ctx, txnHash)
171152
if err != nil {
172153
log.Errorf(
173154
"Failed to fetch transaction %x in block %x at height %d: %s",
174155
txnHash, hash, height, err,
175156
)
157+
if status.Code(err) == codes.Canceled {
158+
return
159+
}
160+
time.Sleep(time.Second)
176161
continue
177162
}
178-
client = spork.AccessNodes.Client()
163+
colData.txns = append(colData.txns, info)
164+
break
165+
}
166+
for {
167+
client := spork.AccessNodes.Client()
179168
txnResult, err := client.TransactionResult(ctx, hash, uint32(txnIndex))
180169
if err != nil {
181170
log.Errorf(
182171
"Failed to fetch transaction result for %x in block %x at height %d: %s",
183172
txnHash, hash, height, err,
184173
)
174+
if status.Code(err) == codes.Canceled {
175+
return
176+
}
177+
time.Sleep(time.Second)
185178
continue
186179
}
187-
colData.txns = append(colData.txns, info)
188180
colData.txnResults = append(colData.txnResults, txnResult)
189181
break
190182
}
@@ -201,30 +193,82 @@ outer:
201193
// the self-sealed root block of a spork (where a ZeroID is used for
202194
// the event collection hash).
203195
if !(spork.Prev != nil && height == spork.RootBlock) {
204-
// TODO(tav): We check for just one transaction in the system
205-
// collection. If this changes in the future, we will need to
206-
// update the logic here to speculatively fetch more transaction
207-
// results.
196+
// We always retrieve the first transaction of the system collection.
208197
txnIndex++
209198
for {
210-
select {
211-
case <-ctx.Done():
212-
return
213-
default:
214-
}
215199
client := spork.AccessNodes.Client()
216200
txnResult, err := client.TransactionResult(ctx, hash, uint32(txnIndex))
217201
if err != nil {
218202
log.Errorf(
219203
"Failed to fetch transaction result at index %d in block %x at height %d: %s",
220204
txnIndex, hash, height, err,
221205
)
206+
if status.Code(err) == codes.Canceled {
207+
return
208+
}
222209
time.Sleep(time.Second)
223210
continue
224211
}
225212
col.txnResults = append(col.txnResults, txnResult)
226213
break
227214
}
215+
if spork.Version >= 8 {
216+
// check if the first tx in the system collection contains events indicating scheduled transactions were run
217+
// We are already on the slow path where GetTransactionsByBlockID/GetTransactionResultsByBlockID has failed
218+
systemTxEvents := col.txnResults[0].Events
219+
scheduledTxs := 0
220+
for _, event := range systemTxEvents {
221+
if strings.HasSuffix(event.Type, ".FlowTransactionScheduler.PendingExecution") {
222+
scheduledTxs++
223+
}
224+
}
225+
// Request scheduled transactions and the final system transaction
226+
fetchSystemTxs:
227+
for range scheduledTxs + 1 {
228+
txnIndex++
229+
for {
230+
client := spork.AccessNodes.Client()
231+
txnResult, err := client.TransactionResult(ctx, hash, uint32(txnIndex))
232+
if err != nil {
233+
log.Errorf(
234+
"Failed to fetch transaction result at index %d in block %x at height %d: %s",
235+
txnIndex, hash, height, err,
236+
)
237+
if status.Code(err) == codes.Canceled {
238+
return
239+
}
240+
if status.Code(err) == codes.NotFound {
241+
// no more transactions available
242+
break fetchSystemTxs
243+
}
244+
time.Sleep(time.Second)
245+
continue
246+
}
247+
col.txnResults = append(col.txnResults, txnResult)
248+
break
249+
}
250+
}
251+
}
252+
// we have the transaction results for the system collection; now fetch transaction infos
253+
for _, result := range col.txnResults {
254+
for {
255+
client := spork.AccessNodes.Client()
256+
info, err := client.Transaction(ctx, result.TransactionId)
257+
if err != nil {
258+
log.Errorf(
259+
"Failed to fetch transaction %x in block %x at height %d: %s",
260+
result.TransactionId, hash, height, err,
261+
)
262+
if status.Code(err) == codes.Canceled {
263+
return
264+
}
265+
time.Sleep(time.Second)
266+
continue
267+
}
268+
col.txns = append(col.txns, info)
269+
break
270+
}
271+
}
228272
}
229273
} else {
230274
col := &collectionData{}
@@ -378,15 +422,9 @@ outer:
378422
newCounter := 0
379423
transfers := 0
380424
for _, col := range cols {
381-
// TODO(tav): We may want to index events from the system collection
382-
// at some point in the future.
383-
if col.system {
384-
continue
385-
}
386425
for idx, txnResult := range col.txnResults {
387426
select {
388427
case <-ctx.Done():
389-
span.End()
390428
return
391429
default:
392430
}

0 commit comments

Comments
 (0)