@@ -3,9 +3,11 @@ package gnosis
3
3
import (
4
4
"context"
5
5
"math"
6
+ "math/big"
6
7
7
8
"github.com/ethereum/go-ethereum/accounts/abi/bind"
8
9
"github.com/ethereum/go-ethereum/core/types"
10
+ "github.com/ethereum/go-ethereum/ethclient"
9
11
"github.com/jackc/pgx/v4"
10
12
"github.com/jackc/pgx/v4/pgxpool"
11
13
"github.com/pkg/errors"
@@ -21,6 +23,7 @@ import (
21
23
type SequencerSyncer struct {
22
24
Contract * sequencerBindings.Sequencer
23
25
DBPool * pgxpool.Pool
26
+ ExecutionClient * ethclient.Client
24
27
StartEon uint64
25
28
GenesisSlotTimestamp uint64
26
29
SecondsPerSlot uint64
@@ -41,69 +44,103 @@ func (s *SequencerSyncer) Sync(ctx context.Context, header *types.Header) error
41
44
} else {
42
45
start = uint64 (syncedUntil .BlockNumber + 1 )
43
46
}
44
-
47
+ endBlock := header . Number . Uint64 ()
45
48
log .Debug ().
46
49
Uint64 ("start-block" , start ).
47
- Uint64 ("end-block" , header . Number . Uint64 () ).
50
+ Uint64 ("end-block" , endBlock ).
48
51
Msg ("syncing sequencer contract" )
49
52
50
- endBlock := header .Number .Uint64 ()
53
+ syncRanges := medley .GetSyncRanges (start , endBlock , maxRequestBlockRange )
54
+ for _ , r := range syncRanges {
55
+ err = s .syncRange (ctx , r [0 ], r [1 ])
56
+ if err != nil {
57
+ return err
58
+ }
59
+ }
60
+ return nil
61
+ }
62
+
63
+ func (s * SequencerSyncer ) syncRange (
64
+ ctx context.Context ,
65
+ start ,
66
+ end uint64 ,
67
+ ) error {
68
+ events , err := s .fetchEvents (ctx , start , end )
69
+ if err != nil {
70
+ return err
71
+ }
72
+ filteredEvents := s .filterEvents (events )
73
+
74
+ header , err := s .ExecutionClient .HeaderByNumber (ctx , new (big.Int ).SetUint64 (end ))
75
+ if err != nil {
76
+ return errors .Wrap (err , "failed to get execution block header by number" )
77
+ }
78
+ err = s .DBPool .BeginFunc (ctx , func (tx pgx.Tx ) error {
79
+ err = s .insertTransactionSubmittedEvents (ctx , tx , filteredEvents )
80
+ if err != nil {
81
+ return err
82
+ }
83
+
84
+ slot := medley .BlockTimestampToSlot (header .Time , s .GenesisSlotTimestamp , s .SecondsPerSlot )
85
+ return database .New (tx ).SetTransactionSubmittedEventsSyncedUntil (ctx , database.SetTransactionSubmittedEventsSyncedUntilParams {
86
+ BlockNumber : int64 (end ),
87
+ BlockHash : header .Hash ().Bytes (),
88
+ Slot : int64 (slot ),
89
+ })
90
+ })
91
+ log .Info ().
92
+ Uint64 ("start-block" , start ).
93
+ Uint64 ("end-block" , end ).
94
+ Int ("num-inserted-events" , len (filteredEvents )).
95
+ Int ("num-discarded-events" , len (events )- len (filteredEvents )).
96
+ Msg ("synced sequencer contract" )
97
+ return nil
98
+ }
99
+
100
+ func (s * SequencerSyncer ) fetchEvents (
101
+ ctx context.Context ,
102
+ start ,
103
+ end uint64 ,
104
+ ) ([]* sequencerBindings.SequencerTransactionSubmitted , error ) {
51
105
opts := bind.FilterOpts {
52
106
Start : start ,
53
- End : & endBlock ,
107
+ End : & end ,
54
108
Context : ctx ,
55
109
}
56
110
it , err := s .Contract .SequencerFilterer .FilterTransactionSubmitted (& opts )
57
111
if err != nil {
58
- return errors .Wrap (err , "failed to query transaction submitted events" )
112
+ return nil , errors .Wrap (err , "failed to query transaction submitted events" )
59
113
}
60
114
events := []* sequencerBindings.SequencerTransactionSubmitted {}
61
115
for it .Next () {
62
- if it .Event .Eon < s .StartEon ||
63
- it .Event .Eon > math .MaxInt64 ||
64
- ! it .Event .GasLimit .IsInt64 () {
65
- log .Debug ().
66
- Uint64 ("eon" , it .Event .Eon ).
67
- Uint64 ("block-number" , it .Event .Raw .BlockNumber ).
68
- Str ("block-hash" , it .Event .Raw .BlockHash .Hex ()).
69
- Uint ("tx-index" , it .Event .Raw .TxIndex ).
70
- Uint ("log-index" , it .Event .Raw .Index ).
71
- Msg ("ignoring transaction submitted event" )
72
- continue
73
- }
74
116
events = append (events , it .Event )
75
117
}
76
118
if it .Error () != nil {
77
- return errors .Wrap (it .Error (), "failed to iterate transaction submitted events" )
78
- }
79
- if len (events ) == 0 {
80
- log .Debug ().
81
- Uint64 ("start-block" , start ).
82
- Uint64 ("end-block" , endBlock ).
83
- Msg ("no transaction submitted events found" )
119
+ return nil , errors .Wrap (it .Error (), "failed to iterate transaction submitted events" )
84
120
}
121
+ return events , nil
122
+ }
85
123
86
- return s .DBPool .BeginFunc (ctx , func (tx pgx.Tx ) error {
87
- err = s .insertTransactionSubmittedEvents (ctx , tx , events )
88
- if err != nil {
89
- return err
90
- }
91
-
92
- newSyncedUntilBlock , err := medley .Uint64ToInt64Safe (endBlock )
93
- if err != nil {
94
- return err
95
- }
96
- slot := medley .BlockTimestampToSlot (header .Time , s .GenesisSlotTimestamp , s .SecondsPerSlot )
97
- err = queries .SetTransactionSubmittedEventsSyncedUntil (ctx , database.SetTransactionSubmittedEventsSyncedUntilParams {
98
- BlockNumber : newSyncedUntilBlock ,
99
- BlockHash : header .Hash ().Bytes (),
100
- Slot : int64 (slot ),
101
- })
102
- if err != nil {
103
- return err
124
+ func (s * SequencerSyncer ) filterEvents (
125
+ events []* sequencerBindings.SequencerTransactionSubmitted ,
126
+ ) []* sequencerBindings.SequencerTransactionSubmitted {
127
+ filteredEvents := []* sequencerBindings.SequencerTransactionSubmitted {}
128
+ for _ , event := range events {
129
+ if event .Eon < s .StartEon ||
130
+ event .Eon > math .MaxInt64 ||
131
+ ! event .GasLimit .IsInt64 () {
132
+ log .Debug ().
133
+ Uint64 ("eon" , event .Eon ).
134
+ Uint64 ("block-number" , event .Raw .BlockNumber ).
135
+ Str ("block-hash" , event .Raw .BlockHash .Hex ()).
136
+ Uint ("tx-index" , event .Raw .TxIndex ).
137
+ Uint ("log-index" , event .Raw .Index ).
138
+ Msg ("ignoring transaction submitted event" )
139
+ continue
104
140
}
105
- return nil
106
- })
141
+ filteredEvents = append (filteredEvents , event )
142
+ }
143
+ return filteredEvents
107
144
}
108
145
109
146
// insertTransactionSubmittedEvents inserts the given events into the database and updates the
0 commit comments