1
1
package block
2
2
3
3
import (
4
- "fmt"
5
4
"log"
6
5
"runtime"
7
6
"time"
8
7
9
8
"github.com/ethereum/go-ethereum/core/types"
10
9
"github.com/ethereum/go-ethereum/ethclient"
11
10
"github.com/gammazero/workerpool"
12
- "github.com/gookit/color"
13
11
cfg "github.com/itzmeanjan/ette/app/config"
14
12
d "github.com/itzmeanjan/ette/app/data"
15
13
"github.com/itzmeanjan/ette/app/db"
14
+ q "github.com/itzmeanjan/ette/app/queue"
16
15
"gorm.io/gorm"
17
16
)
18
17
19
- // HasBlockFinalized - Checking whether block under processing i.e. `number`
20
- // has `N` confirmations on top of it or not
21
- func HasBlockFinalized (status * d.StatusHolder , number uint64 ) bool {
22
-
23
- return status .GetLatestBlockNumber ()- cfg .GetBlockConfirmations () >= number
24
-
25
- }
26
-
27
18
// ProcessBlockContent - Processes everything inside this block i.e. block data, tx data, event data
28
- func ProcessBlockContent (client * ethclient.Client , block * types.Block , _db * gorm.DB , redis * d.RedisInfo , publishable bool , status * d.StatusHolder , startingAt time.Time ) bool {
19
+ func ProcessBlockContent (client * ethclient.Client , block * types.Block , _db * gorm.DB , redis * d.RedisInfo , publishable bool , queue * q. BlockProcessorQueue , status * d.StatusHolder , startingAt time.Time ) bool {
29
20
30
21
// Closure managing publishing whole block data i.e. block header, txn(s), event logs
31
22
// on redis pubsub channel
32
- pubsubWorker := func (txns []* db.PackedTransaction ) * db.PackedBlock {
23
+ pubsubWorker := func (txns []* db.PackedTransaction ) ( * db.PackedBlock , bool ) {
33
24
34
25
// Constructing block data to published & persisted
35
26
packedBlock := BuildPackedBlock (block , txns )
36
27
28
+ // -- 3 step pub/sub attempt
29
+ //
37
30
// Attempting to publish whole block data to redis pubsub channel
38
31
// when eligible `EtteMode` is set
39
32
if publishable && (cfg .Get ("EtteMode" ) == "2" || cfg .Get ("EtteMode" ) == "3" ) {
40
- PublishBlock (packedBlock , redis )
33
+
34
+ // 1. Asking queue whether we need to publish block or not
35
+ if ! queue .CanPublish (block .NumberU64 ()) {
36
+ return packedBlock , true
37
+ }
38
+
39
+ // 2. Attempting to publish block on Pub/Sub topic
40
+ if ! PublishBlock (packedBlock , redis ) {
41
+ return nil , false
42
+ }
43
+
44
+ // 3. Marking this block as published
45
+ if ! queue .Published (block .NumberU64 ()) {
46
+ return nil , false
47
+ }
48
+
41
49
}
50
+ // -- done, with publishing on Pub/Sub topic
42
51
43
- return packedBlock
52
+ return packedBlock , true
44
53
45
54
}
46
55
@@ -49,45 +58,34 @@ func ProcessBlockContent(client *ethclient.Client, block *types.Block, _db *gorm
49
58
// Constructing block data to be persisted
50
59
//
51
60
// This is what we just published on pubsub channel
52
- packedBlock := pubsubWorker (nil )
61
+ packedBlock , ok := pubsubWorker (nil )
62
+ if ! ok {
63
+ return false
64
+ }
53
65
54
66
// If `ette` being run in mode, for only publishing data to
55
67
// pubsub channel, no need to persist data
56
68
//
57
69
// We simply publish & return from execution scope
58
70
if ! (cfg .Get ("EtteMode" ) == "1" || cfg .Get ("EtteMode" ) == "3" ) {
59
71
60
- log .Print ( color . Green . Sprintf ( "[+] Block %d with 0 tx(s) [ Took : %s ]" , block .NumberU64 (), time .Now ().UTC ().Sub (startingAt ) ))
72
+ log .Printf ( "✅ Block %d with 0 tx(s) [ Took : %s ]\n " , block .NumberU64 (), time .Now ().UTC ().Sub (startingAt ))
61
73
status .IncrementBlocksProcessed ()
62
74
63
75
return true
64
76
65
77
}
66
78
67
79
// If block doesn't contain any tx, we'll attempt to persist only block
68
- if err := db .StoreBlock (_db , packedBlock , status ); err != nil {
69
-
70
- log .Print (color .Red .Sprintf ("[+] Failed to process block %d with 0 tx(s) : %s [ Took : %s ]" , block .NumberU64 (), err .Error (), time .Now ().UTC ().Sub (startingAt )))
80
+ if err := db .StoreBlock (_db , packedBlock , status , queue ); err != nil {
71
81
72
- // If failed to persist, we'll put it in retry queue
73
- PushBlockIntoRetryQueue (redis , block .Number ().String ())
82
+ log .Printf ("❗️ Failed to process block %d : %s\n " , block .NumberU64 (), err .Error ())
74
83
return false
75
84
76
85
}
77
86
78
- if ! HasBlockFinalized (status , packedBlock .Block .Number ) {
79
-
80
- log .Print (color .LightRed .Sprintf ("[x] Non-final block %d with 0 tx(s) [ Took : %s | Latest Block : %d | In Queue : %d ]" , packedBlock .Block .Number , time .Now ().UTC ().Sub (startingAt ), status .GetLatestBlockNumber (), GetUnfinalizedQueueLength (redis )))
81
-
82
- // Pushing into unfinalized block queue, to be picked up only when
83
- // finality for this block has been achieved
84
- PushBlockIntoUnfinalizedQueue (redis , fmt .Sprintf ("%d" , packedBlock .Block .Number ))
85
- return true
86
-
87
- }
88
-
89
87
// Successfully processed block
90
- log .Print ( color . Green . Sprintf ( "[+] Block %d with 0 tx(s) [ Took : %s ]" , block .NumberU64 (), time .Now ().UTC ().Sub (startingAt ) ))
88
+ log .Printf ( "✅ Block %d with 0 tx(s) [ Took : %s ]\n " , block .NumberU64 (), time .Now ().UTC ().Sub (startingAt ))
91
89
status .IncrementBlocksProcessed ()
92
90
93
91
return true
@@ -160,57 +158,41 @@ func ProcessBlockContent(client *ethclient.Client, block *types.Block, _db *gorm
160
158
wp .Stop ()
161
159
// -- Tx processing ending
162
160
163
- // When all tx(s) aren't successfully processed ( as they have informed us over go channel ),
164
- // we're exiting from this context, while putting this block number in retry queue
165
161
if ! (result .Failure == 0 ) {
166
-
167
- PushBlockIntoRetryQueue (redis , block .Number ().String ())
168
162
return false
169
-
170
163
}
171
164
172
165
// Constructing block data to be persisted
173
166
//
174
167
// This is what we just published on pubsub channel
175
- packedBlock := pubsubWorker (packedTxs )
168
+ packedBlock , ok := pubsubWorker (packedTxs )
169
+ if ! ok {
170
+ return false
171
+ }
176
172
177
173
// If `ette` being run in mode, for only publishing data to
178
174
// pubsub channel, no need to persist data
179
175
//
180
176
// We simply publish & return from execution scope
181
177
if ! (cfg .Get ("EtteMode" ) == "1" || cfg .Get ("EtteMode" ) == "3" ) {
182
178
183
- log .Print ( color . Green . Sprintf ( "[+] Block %d with %d tx(s) [ Took : %s ]" , block .NumberU64 (), block .Transactions ().Len (), time .Now ().UTC ().Sub (startingAt ) ))
179
+ log .Printf ( "✅ Block %d with %d tx(s) [ Took : %s ]\n " , block .NumberU64 (), block .Transactions ().Len (), time .Now ().UTC ().Sub (startingAt ))
184
180
status .IncrementBlocksProcessed ()
185
181
186
182
return true
187
183
188
184
}
189
185
190
186
// If block doesn't contain any tx, we'll attempt to persist only block
191
- if err := db .StoreBlock (_db , packedBlock , status ); err != nil {
187
+ if err := db .StoreBlock (_db , packedBlock , status , queue ); err != nil {
192
188
193
- log .Print (color .Red .Sprintf ("[+] Failed to process block %d with %d tx(s) : %s [ Took : %s ]" , block .NumberU64 (), block .Transactions ().Len (), err .Error (), time .Now ().UTC ().Sub (startingAt )))
194
-
195
- // If failed to persist, we'll put it in retry queue
196
- PushBlockIntoRetryQueue (redis , block .Number ().String ())
189
+ log .Printf ("❗️ Failed to process block %d : %s\n " , block .NumberU64 (), err .Error ())
197
190
return false
198
191
199
192
}
200
193
201
- if ! HasBlockFinalized (status , packedBlock .Block .Number ) {
202
-
203
- log .Print (color .LightRed .Sprintf ("[x] Non-final block %d with %d tx(s) [ Took : %s | Latest Block : %d | In Queue : %d ]" , packedBlock .Block .Number , block .Transactions ().Len (), time .Now ().UTC ().Sub (startingAt ), status .GetLatestBlockNumber (), GetUnfinalizedQueueLength (redis )))
204
-
205
- // Pushing into unfinalized block queue, to be picked up only when
206
- // finality for this block has been achieved
207
- PushBlockIntoUnfinalizedQueue (redis , fmt .Sprintf ("%d" , packedBlock .Block .Number ))
208
- return true
209
-
210
- }
211
-
212
194
// Successfully processed block
213
- log .Print ( color . Green . Sprintf ( "[+] Block %d with %d tx(s) [ Took : %s ]" , block .NumberU64 (), block .Transactions ().Len (), time .Now ().UTC ().Sub (startingAt ) ))
195
+ log .Printf ( "✅ Block %d with %d tx(s) [ Took : %s ]\n " , block .NumberU64 (), block .Transactions ().Len (), time .Now ().UTC ().Sub (startingAt ))
214
196
215
197
status .IncrementBlocksProcessed ()
216
198
return true
0 commit comments