@@ -32,25 +32,23 @@ import (
32
32
)
33
33
34
34
type Service struct {
35
- host host.Host
36
- network * utils.Network
37
- client * Client // todo: merge all the functionality of Client with p2p SyncService
38
-
39
35
blockchain * blockchain.Blockchain
40
- listener junoSync.EventListener
41
36
log utils.SimpleLogger
42
37
43
- blockCh chan BlockBody
38
+ blockFetcher * BlockFetcher
39
+ blockCh chan BlockBody
44
40
}
45
41
46
- func New (bc * blockchain.Blockchain , h host.Host , n * utils.Network , log utils.SimpleLogger ) * Service {
42
+ func New (
43
+ bc * blockchain.Blockchain ,
44
+ log utils.SimpleLogger ,
45
+ blockFetcher * BlockFetcher ,
46
+ ) * Service {
47
47
return & Service {
48
- host : h ,
49
- network : n ,
50
- blockchain : bc ,
51
- log : log ,
52
- listener : & junoSync.SelectiveListener {},
53
- blockCh : make (chan BlockBody ),
48
+ blockchain : bc ,
49
+ log : log ,
50
+ blockFetcher : blockFetcher ,
51
+ blockCh : make (chan BlockBody ),
54
52
}
55
53
}
56
54
@@ -63,8 +61,6 @@ func (s *Service) Run(ctx context.Context) {
63
61
defer cancel ()
64
62
defer close (s .blockCh )
65
63
66
- s .client = NewClient (s .randomPeerStream , s .network , s .log )
67
-
68
64
for i := 0 ; ; i ++ {
69
65
if err := ctx .Err (); err != nil {
70
66
break
@@ -83,7 +79,7 @@ func (s *Service) Run(ctx context.Context) {
83
79
84
80
// todo change iteration to fetch several objects uint64(min(blockBehind, maxBlocks))
85
81
blockNumber := uint64 (nextHeight )
86
- if err = s .processBlock (iterCtx , blockNumber ); err != nil {
82
+ if err = s .blockFetcher . ProcessBlock (iterCtx , blockNumber , s . blockCh ); err != nil {
87
83
s .logError ("Failed to process block" , fmt .Errorf ("blockNumber: %d, err: %w" , blockNumber , err ))
88
84
cancelIteration ()
89
85
continue
@@ -92,6 +88,10 @@ func (s *Service) Run(ctx context.Context) {
92
88
}
93
89
}
94
90
91
+ func (s * Service ) WithListener (l junoSync.EventListener ) {
92
+ s .blockFetcher .WithListener (l )
93
+ }
94
+
95
95
func (s * Service ) getNextHeight () (int , error ) {
96
96
curHeight , err := s .blockchain .Height ()
97
97
if err == nil {
@@ -102,7 +102,50 @@ func (s *Service) getNextHeight() (int, error) {
102
102
return 0 , err
103
103
}
104
104
105
- func (s * Service ) processBlock (ctx context.Context , blockNumber uint64 ) error {
105
+ func (s * Service ) logError (msg string , err error ) {
106
+ if ! errors .Is (err , context .Canceled ) {
107
+ var log utils.SimpleLogger
108
+ if v , ok := s .log .(* utils.ZapLogger ); ok {
109
+ enhancedLogger := v .SugaredLogger .Desugar ().WithOptions (zap .AddCallerSkip (1 )).Sugar ()
110
+ log = & utils.ZapLogger {SugaredLogger : enhancedLogger }
111
+ } else {
112
+ log = s .log
113
+ }
114
+
115
+ log .Errorw (msg , "err" , err )
116
+ } else {
117
+ s .log .Debugw ("Sync context canceled" )
118
+ }
119
+ }
120
+
121
+ type BlockFetcher struct {
122
+ network * utils.Network
123
+ client * Client // todo: merge all the functionality of Client with p2p SyncService
124
+ blockchain * blockchain.Blockchain
125
+ listener junoSync.EventListener
126
+ log utils.SimpleLogger
127
+ }
128
+
129
+ func NewBlockFetcher (
130
+ bc * blockchain.Blockchain ,
131
+ h host.Host ,
132
+ n * utils.Network ,
133
+ log utils.SimpleLogger ,
134
+ ) BlockFetcher {
135
+ return BlockFetcher {
136
+ network : n ,
137
+ blockchain : bc ,
138
+ log : log ,
139
+ listener : & junoSync.SelectiveListener {},
140
+ client : NewClient (randomPeerStream (h , log ), n , log ),
141
+ }
142
+ }
143
+
144
+ func (s * BlockFetcher ) ProcessBlock (
145
+ ctx context.Context ,
146
+ blockNumber uint64 ,
147
+ outputs chan <- BlockBody ,
148
+ ) error {
106
149
headersAndSigsCh , err := s .genHeadersAndSigs (ctx , blockNumber )
107
150
if err != nil {
108
151
return fmt .Errorf ("failed to get block headers parts: %w" , err )
@@ -130,7 +173,7 @@ func (s *Service) processBlock(ctx context.Context, blockNumber uint64) error {
130
173
131
174
pipeline .Bridge (
132
175
ctx ,
133
- s . blockCh ,
176
+ outputs ,
134
177
s .processSpecBlockParts (
135
178
ctx ,
136
179
blockNumber ,
@@ -151,22 +194,6 @@ func specBlockPartsFunc[T specBlockHeaderAndSigs | specTxWithReceipts | specEven
151
194
return specBlockParts (i )
152
195
}
153
196
154
- func (s * Service ) logError (msg string , err error ) {
155
- if ! errors .Is (err , context .Canceled ) {
156
- var log utils.SimpleLogger
157
- if v , ok := s .log .(* utils.ZapLogger ); ok {
158
- enhancedLogger := v .SugaredLogger .Desugar ().WithOptions (zap .AddCallerSkip (1 )).Sugar ()
159
- log = & utils.ZapLogger {SugaredLogger : enhancedLogger }
160
- } else {
161
- log = s .log
162
- }
163
-
164
- log .Errorw (msg , "err" , err )
165
- } else {
166
- s .log .Debugw ("Sync context canceled" )
167
- }
168
- }
169
-
170
197
// BlockBody is used to mange all the different parts of the blocks require to store the block in the blockchain.Store()
171
198
type BlockBody struct {
172
199
Block * core.Block
@@ -177,7 +204,7 @@ type BlockBody struct {
177
204
}
178
205
179
206
//nolint:gocyclo
180
- func (s * Service ) processSpecBlockParts (
207
+ func (s * BlockFetcher ) processSpecBlockParts (
181
208
ctx context.Context , startingBlockNum uint64 , specBlockPartsCh <- chan specBlockParts ,
182
209
) <- chan <- chan BlockBody {
183
210
orderedBlockBodiesCh := make (chan (<- chan BlockBody ))
@@ -270,7 +297,7 @@ func (s *Service) processSpecBlockParts(
270
297
}
271
298
272
299
//nolint:gocyclo,funlen
273
- func (s * Service ) adaptAndSanityCheckBlock (
300
+ func (s * BlockFetcher ) adaptAndSanityCheckBlock (
274
301
ctx context.Context ,
275
302
header * header.SignedBlockHeader ,
276
303
contractDiffs []* state.ContractDiff ,
@@ -431,7 +458,10 @@ func (s specBlockHeaderAndSigs) blockNumber() uint64 {
431
458
return s .header .Number
432
459
}
433
460
434
- func (s * Service ) genHeadersAndSigs (ctx context.Context , blockNumber uint64 ) (<- chan specBlockHeaderAndSigs , error ) {
461
+ func (s * BlockFetcher ) genHeadersAndSigs (
462
+ ctx context.Context ,
463
+ blockNumber uint64 ,
464
+ ) (<- chan specBlockHeaderAndSigs , error ) {
435
465
it := s .createIteratorForBlock (blockNumber )
436
466
headersIt , err := s .client .RequestBlockHeaders (ctx , & header.BlockHeadersRequest {Iteration : it })
437
467
if err != nil {
@@ -475,7 +505,10 @@ func (s specClasses) blockNumber() uint64 {
475
505
return s .number
476
506
}
477
507
478
- func (s * Service ) genClasses (ctx context.Context , blockNumber uint64 ) (<- chan specClasses , error ) {
508
+ func (s * BlockFetcher ) genClasses (
509
+ ctx context.Context ,
510
+ blockNumber uint64 ,
511
+ ) (<- chan specClasses , error ) {
479
512
it := s .createIteratorForBlock (blockNumber )
480
513
classesIt , err := s .client .RequestClasses (ctx , & syncclass.ClassesRequest {Iteration : it })
481
514
if err != nil {
@@ -521,7 +554,10 @@ func (s specContractDiffs) blockNumber() uint64 {
521
554
return s .number
522
555
}
523
556
524
- func (s * Service ) genStateDiffs (ctx context.Context , blockNumber uint64 ) (<- chan specContractDiffs , error ) {
557
+ func (s * BlockFetcher ) genStateDiffs (
558
+ ctx context.Context ,
559
+ blockNumber uint64 ,
560
+ ) (<- chan specContractDiffs , error ) {
525
561
it := s .createIteratorForBlock (blockNumber )
526
562
stateDiffsIt , err := s .client .RequestStateDiffs (ctx , & state.StateDiffsRequest {Iteration : it })
527
563
if err != nil {
@@ -569,7 +605,10 @@ func (s specEvents) blockNumber() uint64 {
569
605
return s .number
570
606
}
571
607
572
- func (s * Service ) genEvents (ctx context.Context , blockNumber uint64 ) (<- chan specEvents , error ) {
608
+ func (s * BlockFetcher ) genEvents (
609
+ ctx context.Context ,
610
+ blockNumber uint64 ,
611
+ ) (<- chan specEvents , error ) {
573
612
it := s .createIteratorForBlock (blockNumber )
574
613
eventsIt , err := s .client .RequestEvents (ctx , & event.EventsRequest {Iteration : it })
575
614
if err != nil {
@@ -616,7 +655,10 @@ func (s specTxWithReceipts) blockNumber() uint64 {
616
655
return s .number
617
656
}
618
657
619
- func (s * Service ) genTransactions (ctx context.Context , blockNumber uint64 ) (<- chan specTxWithReceipts , error ) {
658
+ func (s * BlockFetcher ) genTransactions (
659
+ ctx context.Context ,
660
+ blockNumber uint64 ,
661
+ ) (<- chan specTxWithReceipts , error ) {
620
662
it := s .createIteratorForBlock (blockNumber )
621
663
txsIt , err := s .client .RequestTransactions (ctx , & synctransaction.TransactionsRequest {Iteration : it })
622
664
if err != nil {
@@ -662,47 +704,49 @@ func (s *Service) genTransactions(ctx context.Context, blockNumber uint64) (<-ch
662
704
return txsCh , nil
663
705
}
664
706
665
- func ( s * Service ) randomPeer ( ) peer.ID {
666
- store := s . host .Peerstore ()
707
+ func randomPeer ( host host. Host , log utils. SimpleLogger ) peer.ID {
708
+ store := host .Peerstore ()
667
709
// todo do not request same block from all peers
668
710
peers := utils .Filter (store .Peers (), func (peerID peer.ID ) bool {
669
- return peerID != s . host .ID ()
711
+ return peerID != host .ID ()
670
712
})
671
713
if len (peers ) == 0 {
672
714
return ""
673
715
}
674
716
675
717
p := peers [rand .Intn (len (peers ))] //nolint:gosec
676
718
677
- s . log .Debugw ("Number of peers" , "len" , len (peers ))
678
- s . log .Debugw ("Random chosen peer's info" , "peerInfo" , store .PeerInfo (p ))
719
+ log .Debugw ("Number of peers" , "len" , len (peers ))
720
+ log .Debugw ("Random chosen peer's info" , "peerInfo" , store .PeerInfo (p ))
679
721
680
722
return p
681
723
}
682
724
683
725
var errNoPeers = errors .New ("no peers available" )
684
726
685
- func (s * Service ) randomPeerStream (ctx context.Context , pids ... protocol.ID ) (network.Stream , error ) {
686
- randPeer := s .randomPeer ()
687
- if randPeer == "" {
688
- return nil , errNoPeers
689
- }
690
- stream , err := s .host .NewStream (ctx , randPeer , pids ... )
691
- if err != nil {
692
- s .log .Debugw ("Error creating stream" , "peer" , randPeer , "err" , err )
693
- s .removePeer (randPeer )
694
- return nil , err
727
+ func randomPeerStream (host host.Host , log utils.SimpleLogger ) NewStreamFunc {
728
+ return func (ctx context.Context , pids ... protocol.ID ) (network.Stream , error ) {
729
+ randPeer := randomPeer (host , log )
730
+ if randPeer == "" {
731
+ return nil , errNoPeers
732
+ }
733
+ stream , err := host .NewStream (ctx , randPeer , pids ... )
734
+ if err != nil {
735
+ log .Debugw ("Error creating stream" , "peer" , randPeer , "err" , err )
736
+ removePeer (host , log , randPeer )
737
+ return nil , err
738
+ }
739
+ return stream , err
695
740
}
696
- return stream , err
697
741
}
698
742
699
- func ( s * Service ) removePeer ( id peer.ID ) {
700
- s . log .Debugw ("Removing peer" , "peerID" , id )
701
- s . host .Peerstore ().RemovePeer (id )
702
- s . host .Peerstore ().ClearAddrs (id )
743
+ func removePeer ( host host. Host , log utils. SimpleLogger , id peer.ID ) {
744
+ log .Debugw ("Removing peer" , "peerID" , id )
745
+ host .Peerstore ().RemovePeer (id )
746
+ host .Peerstore ().ClearAddrs (id )
703
747
}
704
748
705
- func (s * Service ) createIteratorForBlock (blockNumber uint64 ) * synccommon.Iteration {
749
+ func (s * BlockFetcher ) createIteratorForBlock (blockNumber uint64 ) * synccommon.Iteration {
706
750
return & synccommon.Iteration {
707
751
Start : & synccommon.Iteration_BlockNumber {BlockNumber : blockNumber },
708
752
Direction : synccommon .Iteration_Forward ,
@@ -711,6 +755,6 @@ func (s *Service) createIteratorForBlock(blockNumber uint64) *synccommon.Iterati
711
755
}
712
756
}
713
757
714
- func (s * Service ) WithListener (l junoSync.EventListener ) {
758
+ func (s * BlockFetcher ) WithListener (l junoSync.EventListener ) {
715
759
s .listener = l
716
760
}
0 commit comments