@@ -3,6 +3,7 @@ package builder
3
3
import (
4
4
"context"
5
5
"errors"
6
+ "fmt"
6
7
stdsync "sync"
7
8
"time"
8
9
@@ -15,6 +16,7 @@ import (
15
16
"github.com/NethermindEth/juno/feed"
16
17
"github.com/NethermindEth/juno/mempool"
17
18
"github.com/NethermindEth/juno/service"
19
+ "github.com/NethermindEth/juno/starknetdata"
18
20
"github.com/NethermindEth/juno/sync"
19
21
"github.com/NethermindEth/juno/utils"
20
22
"github.com/NethermindEth/juno/vm"
@@ -42,6 +44,10 @@ type Builder struct {
42
44
pendingBlock blockchain.Pending
43
45
headState core.StateReader
44
46
headCloser blockchain.StateCloser
47
+
48
+ bootstrap bool
49
+ bootstrapToBlock uint64
50
+ starknetData starknetdata.StarknetData // To bootstrap sequencer
45
51
}
46
52
47
53
func New (privKey * ecdsa.PrivateKey , ownAddr * felt.Felt , bc * blockchain.Blockchain , builderVM vm.VM ,
@@ -66,12 +72,53 @@ func (b *Builder) WithEventListener(l EventListener) *Builder {
66
72
return b
67
73
}
68
74
75
+ func (b * Builder ) WithBootstrap (bootstrap bool ) * Builder {
76
+ b .bootstrap = bootstrap
77
+ return b
78
+ }
79
+
80
+ func (b * Builder ) WithStarknetData (starknetData starknetdata.StarknetData ) * Builder {
81
+ b .starknetData = starknetData
82
+ return b
83
+ }
84
+
85
+ func (b * Builder ) WithBootstrapToBlock (bootstrapToBlock uint64 ) * Builder {
86
+ b .bootstrapToBlock = bootstrapToBlock
87
+ return b
88
+ }
89
+
90
+ func (b * Builder ) BootstrapSeq (ctx context.Context , toBlockNum uint64 ) error {
91
+ var i uint64
92
+ for i = 0 ; i < toBlockNum ; i ++ {
93
+ block , su , classes , err := b .getSyncData (i )
94
+ if err != nil {
95
+ return err
96
+ }
97
+ commitments , err := b .bc .SanityCheckNewHeight (block , su , classes )
98
+ if err != nil {
99
+ return err
100
+ }
101
+ err = b .bc .Store (block , commitments , su , classes )
102
+ if err != nil {
103
+ return err
104
+ }
105
+ }
106
+ return nil
107
+ }
108
+
69
109
func (b * Builder ) Run (ctx context.Context ) error {
70
- if err := b .initPendingBlock (); err != nil {
110
+ if b .bootstrap {
111
+ err := b .BootstrapSeq (ctx , b .bootstrapToBlock )
112
+ if err != nil {
113
+ return err
114
+ }
115
+ }
116
+
117
+ if err := b .InitPendingBlock (); err != nil {
71
118
return err
72
119
}
73
120
defer func () {
74
- if pErr := b .clearPending (); pErr != nil {
121
+ if pErr := b .ClearPending (); pErr != nil {
75
122
b .log .Errorw ("clearing pending" , "err" , pErr )
76
123
}
77
124
}()
@@ -90,14 +137,15 @@ func (b *Builder) Run(ctx context.Context) error {
90
137
<- doneListen
91
138
return nil
92
139
case <- time .After (b .blockTime ):
140
+ b .log .Debugw ("Finalising new block" )
93
141
if err := b .Finalise (); err != nil {
94
142
return err
95
143
}
96
144
}
97
145
}
98
146
}
99
147
100
- func (b * Builder ) initPendingBlock () error {
148
+ func (b * Builder ) InitPendingBlock () error {
101
149
if b .pendingBlock .Block != nil {
102
150
return nil
103
151
}
@@ -117,7 +165,7 @@ func (b *Builder) initPendingBlock() error {
117
165
return err
118
166
}
119
167
120
- func (b * Builder ) clearPending () error {
168
+ func (b * Builder ) ClearPending () error {
121
169
b .pendingBlock = blockchain.Pending {}
122
170
if b .headState != nil {
123
171
if err := b .headCloser (); err != nil {
@@ -137,14 +185,16 @@ func (b *Builder) Finalise() error {
137
185
if err := b .bc .Finalise (& b .pendingBlock , b .Sign ); err != nil {
138
186
return err
139
187
}
188
+ fmt .Sprintln ("Finalised block" , "number" , b .pendingBlock .Block .Number , "hash" ,
189
+ b .pendingBlock .Block .Hash .ShortString (), "state" , b .pendingBlock .Block .GlobalStateRoot .ShortString ())
140
190
b .log .Infow ("Finalised block" , "number" , b .pendingBlock .Block .Number , "hash" ,
141
191
b .pendingBlock .Block .Hash .ShortString (), "state" , b .pendingBlock .Block .GlobalStateRoot .ShortString ())
142
192
b .listener .OnBlockFinalised (b .pendingBlock .Block .Header )
143
193
144
- if err := b .clearPending (); err != nil {
194
+ if err := b .ClearPending (); err != nil {
145
195
return err
146
196
}
147
- return b .initPendingBlock ()
197
+ return b .InitPendingBlock ()
148
198
}
149
199
150
200
// ValidateAgainstPendingState validates a user transaction against the pending state
@@ -261,7 +311,6 @@ func (b *Builder) depletePool(ctx context.Context) error {
261
311
if ! errors .As (err , & txnExecutionError ) {
262
312
return err
263
313
}
264
-
265
314
b .log .Debugw ("failed txn" , "hash" , userTxn .Transaction .Hash ().String (), "err" , err .Error ())
266
315
}
267
316
@@ -311,3 +360,28 @@ func (b *Builder) runTxn(txn *mempool.BroadcastedTransaction) error {
311
360
b .pendingBlock .Block .EventCount += uint64 (len (receipt .Events ))
312
361
return nil
313
362
}
363
+
364
+ func (b * Builder ) getSyncData (blockNumber uint64 ) (* core.Block , * core.StateUpdate ,
365
+ map [felt.Felt ]core.Class , error ,
366
+ ) {
367
+ block , err := b .starknetData .BlockByNumber (context .Background (), blockNumber )
368
+ if err != nil {
369
+ return nil , nil , nil , err
370
+ }
371
+ su , err := b .starknetData .StateUpdate (context .Background (), blockNumber )
372
+ if err != nil {
373
+ return nil , nil , nil , err
374
+ }
375
+ txns := block .Transactions
376
+ classes := make (map [felt.Felt ]core.Class )
377
+ for _ , txn := range txns {
378
+ if t , ok := txn .(* core.DeclareTransaction ); ok {
379
+ class , err := b .starknetData .Class (context .Background (), t .ClassHash )
380
+ if err != nil {
381
+ return nil , nil , nil , err
382
+ }
383
+ classes [* t .ClassHash ] = class
384
+ }
385
+ }
386
+ return block , su , classes , nil
387
+ }
0 commit comments