6
6
"sync"
7
7
"time"
8
8
9
+ "github.com/filecoin-project/go-state-types/abi"
9
10
actorstypes "github.com/filecoin-project/go-state-types/actors"
11
+ "github.com/filecoin-project/go-state-types/manifest"
10
12
"github.com/filecoin-project/lotus/chain/types"
11
13
"github.com/ipfs/go-cid"
12
14
logging "github.com/ipfs/go-log/v2"
@@ -66,10 +68,15 @@ import (
66
68
fevmtransactiontask "github.com/filecoin-project/lily/tasks/fevm/transaction"
67
69
fevmactorstatstask "github.com/filecoin-project/lily/tasks/fevmactorstats"
68
70
71
+ // actor dump
72
+ fevmactordumptask "github.com/filecoin-project/lily/tasks/periodic_actor_dump/fevm_actor"
73
+
69
74
"github.com/filecoin-project/lily/chain/indexer/tasktype"
70
75
"github.com/filecoin-project/lily/metrics"
71
76
"github.com/filecoin-project/lily/model"
72
77
visormodel "github.com/filecoin-project/lily/model/visor"
78
+
79
+ builtin "github.com/filecoin-project/lotus/chain/actors/builtin"
73
80
)
74
81
75
82
type TipSetProcessor interface {
@@ -79,6 +86,13 @@ type TipSetProcessor interface {
79
86
ProcessTipSet (ctx context.Context , current * types.TipSet ) (model.Persistable , * visormodel.ProcessingReport , error )
80
87
}
81
88
89
+ type PeriodicActorDumpProcessor interface {
90
+ // ProcessTipSet processes a tipset. If error is non-nil then the processor encountered a fatal error.
91
+ // Any data returned must be accompanied by a processing report.
92
+ // Implementations of this interface must abort processing when their context is canceled.
93
+ ProcessPeriodicActorDump (ctx context.Context , current * types.TipSet , actors tasks.ActorStatesByType ) (model.Persistable , * visormodel.ProcessingReport , error )
94
+ }
95
+
82
96
type TipSetsProcessor interface {
83
97
// ProcessTipSets processes sequential tipsts (a parent and a child, or an executed and a current). If error is non-nil then the processor encountered a fatal error.
84
98
// Any data returned must be accompanied by a processing report.
@@ -111,20 +125,22 @@ func New(api tasks.DataSource, name string, taskNames []string) (*StateProcessor
111
125
return nil , err
112
126
}
113
127
return & StateProcessor {
114
- builtinProcessors : processors .ReportProcessors ,
115
- tipsetProcessors : processors .TipsetProcessors ,
116
- tipsetsProcessors : processors .TipsetsProcessors ,
117
- actorProcessors : processors .ActorProcessors ,
118
- api : api ,
119
- name : name ,
128
+ builtinProcessors : processors .ReportProcessors ,
129
+ tipsetProcessors : processors .TipsetProcessors ,
130
+ tipsetsProcessors : processors .TipsetsProcessors ,
131
+ actorProcessors : processors .ActorProcessors ,
132
+ periodicActorDumpProcessors : processors .PeriodicActorDumpProcessors ,
133
+ api : api ,
134
+ name : name ,
120
135
}, nil
121
136
}
122
137
123
138
type StateProcessor struct {
124
- builtinProcessors map [string ]ReportProcessor
125
- tipsetProcessors map [string ]TipSetProcessor
126
- tipsetsProcessors map [string ]TipSetsProcessor
127
- actorProcessors map [string ]ActorProcessor
139
+ builtinProcessors map [string ]ReportProcessor
140
+ tipsetProcessors map [string ]TipSetProcessor
141
+ tipsetsProcessors map [string ]TipSetsProcessor
142
+ actorProcessors map [string ]ActorProcessor
143
+ periodicActorDumpProcessors map [string ]PeriodicActorDumpProcessor
128
144
129
145
// api used by tasks
130
146
api tasks.DataSource
@@ -151,17 +167,18 @@ type Result struct {
151
167
// emits results of the state extraction closing when processing is completed. It is the responsibility of the processors
152
168
// to abort if its context is canceled.
153
169
// A list of all tasks executing is returned.
154
- func (sp * StateProcessor ) State (ctx context.Context , current , executed * types.TipSet ) (chan * Result , []string ) {
170
+ func (sp * StateProcessor ) State (ctx context.Context , current , executed * types.TipSet , interval int ) (chan * Result , []string ) {
155
171
ctx , span := otel .Tracer ("" ).Start (ctx , "StateProcessor.State" )
156
172
157
- num := len (sp .tipsetProcessors ) + len (sp .actorProcessors ) + len (sp .tipsetsProcessors ) + len (sp .builtinProcessors )
173
+ num := len (sp .tipsetProcessors ) + len (sp .actorProcessors ) + len (sp .tipsetsProcessors ) + len (sp .builtinProcessors ) + len ( sp . periodicActorDumpProcessors )
158
174
results := make (chan * Result , num )
159
175
taskNames := make ([]string , 0 , num )
160
176
161
177
taskNames = append (taskNames , sp .startReport (ctx , current , results )... )
162
178
taskNames = append (taskNames , sp .startTipSet (ctx , current , results )... )
163
179
taskNames = append (taskNames , sp .startTipSets (ctx , current , executed , results )... )
164
180
taskNames = append (taskNames , sp .startActor (ctx , current , executed , results )... )
181
+ taskNames = append (taskNames , sp .startPeriodicActorDump (ctx , current , interval , results )... )
165
182
166
183
go func () {
167
184
sp .pwg .Wait ()
@@ -398,19 +415,95 @@ func (sp *StateProcessor) startActor(ctx context.Context, current, executed *typ
398
415
return taskNames
399
416
}
400
417
418
+ // startPeriodicActorDump starts all TipSetsProcessor's in parallel, their results are emitted on the `results` channel.
419
+ // A list containing all executed task names is returned.
420
+ func (sp * StateProcessor ) startPeriodicActorDump (ctx context.Context , current * types.TipSet , interval int , results chan * Result ) []string {
421
+ start := time .Now ()
422
+ var taskNames []string
423
+
424
+ if interval > 0 && current .Height ()% abi .ChainEpoch (interval ) != 0 {
425
+ logger := log .With ("processor" , "PeriodicActorDump" )
426
+ logger .Infow ("Skip this epoch" , current .Height ())
427
+ return taskNames
428
+ }
429
+
430
+ actors := make (map [string ][]* types.ActorV5 )
431
+ addrssArr , _ := sp .api .StateListActors (ctx , current .Key ())
432
+
433
+ for _ , address := range addrssArr {
434
+ actor , err := sp .api .Actor (ctx , address , current .Key ())
435
+ if err != nil {
436
+ continue
437
+ }
438
+
439
+ // EVM Actor
440
+ if builtin .IsEvmActor (actor .Code ) {
441
+ actors [manifest .EvmKey ] = append (actors [manifest .EvmKey ], actor )
442
+ } else if builtin .IsEthAccountActor (actor .Code ) {
443
+ actors [manifest .EthAccountKey ] = append (actors [manifest .EthAccountKey ], actor )
444
+ } else if builtin .IsPlaceholderActor (actor .Code ) {
445
+ actors [manifest .PlaceholderKey ] = append (actors [manifest .PlaceholderKey ], actor )
446
+ }
447
+ }
448
+
449
+ for taskName , proc := range sp .periodicActorDumpProcessors {
450
+ name := taskName
451
+ p := proc
452
+ taskNames = append (taskNames , name )
453
+
454
+ sp .pwg .Add (1 )
455
+ go func () {
456
+ ctx , _ = tag .New (ctx , tag .Upsert (metrics .TaskType , name ))
457
+ stats .Record (ctx , metrics .TipsetHeight .M (int64 (current .Height ())))
458
+ stop := metrics .Timer (ctx , metrics .ProcessingDuration )
459
+ defer stop ()
460
+
461
+ pl := log .With ("task" , name , "height" , current .Height (), "reporter" , sp .name )
462
+ pl .Infow ("PeriodicActorDump processor started" )
463
+ defer func () {
464
+ pl .Infow ("processor ended" , "duration" , time .Since (start ))
465
+ sp .pwg .Done ()
466
+ }()
467
+
468
+ data , report , err := p .ProcessPeriodicActorDump (ctx , current , actors )
469
+ if err != nil {
470
+ stats .Record (ctx , metrics .ProcessingFailure .M (1 ))
471
+ results <- & Result {
472
+ Task : name ,
473
+ Error : err ,
474
+ StartedAt : start ,
475
+ CompletedAt : time .Now (),
476
+ }
477
+ pl .Errorw ("processor error" , "error" , err )
478
+ return
479
+ }
480
+ results <- & Result {
481
+ Task : name ,
482
+ Report : visormodel.ProcessingReportList {report },
483
+ Data : data ,
484
+ StartedAt : start ,
485
+ CompletedAt : time .Now (),
486
+ }
487
+ }()
488
+ }
489
+ return taskNames
490
+ }
491
+
401
492
type IndexerProcessors struct {
402
- TipsetProcessors map [string ]TipSetProcessor
403
- TipsetsProcessors map [string ]TipSetsProcessor
404
- ActorProcessors map [string ]ActorProcessor
405
- ReportProcessors map [string ]ReportProcessor
493
+ TipsetProcessors map [string ]TipSetProcessor
494
+ TipsetsProcessors map [string ]TipSetsProcessor
495
+ ActorProcessors map [string ]ActorProcessor
496
+ ReportProcessors map [string ]ReportProcessor
497
+ PeriodicActorDumpProcessors map [string ]PeriodicActorDumpProcessor
406
498
}
407
499
408
500
func MakeProcessors (api tasks.DataSource , indexerTasks []string ) (* IndexerProcessors , error ) {
409
501
out := & IndexerProcessors {
410
- TipsetProcessors : make (map [string ]TipSetProcessor ),
411
- TipsetsProcessors : make (map [string ]TipSetsProcessor ),
412
- ActorProcessors : make (map [string ]ActorProcessor ),
413
- ReportProcessors : make (map [string ]ReportProcessor ),
502
+ TipsetProcessors : make (map [string ]TipSetProcessor ),
503
+ TipsetsProcessors : make (map [string ]TipSetsProcessor ),
504
+ ActorProcessors : make (map [string ]ActorProcessor ),
505
+ ReportProcessors : make (map [string ]ReportProcessor ),
506
+ PeriodicActorDumpProcessors : make (map [string ]PeriodicActorDumpProcessor ),
414
507
}
415
508
for _ , t := range indexerTasks {
416
509
switch t {
@@ -687,6 +780,12 @@ func MakeProcessors(api tasks.DataSource, indexerTasks []string) (*IndexerProces
687
780
case tasktype .FEVMTrace :
688
781
out .TipsetsProcessors [t ] = fevmtracetask .NewTask (api )
689
782
783
+ //
784
+ // Dump
785
+ //
786
+ case tasktype .FEVMActorDump :
787
+ out .PeriodicActorDumpProcessors [t ] = fevmactordumptask .NewTask (api )
788
+
690
789
case BuiltinTaskName :
691
790
out .ReportProcessors [t ] = indexertask .NewTask (api )
692
791
default :
0 commit comments