Skip to content

Commit 5304947

Browse files
committed
Integrate the snapshotbatch with Juno
1 parent 9999401 commit 5304947

File tree

12 files changed

+405
-100
lines changed

12 files changed

+405
-100
lines changed

blockchain/blockchain.go

Lines changed: 104 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ func (b *Blockchain) Network() *utils.Network {
9999
// If blockchain is empty zero felt is returned.
100100
func (b *Blockchain) StateCommitment() (felt.Felt, error) {
101101
b.listener.OnRead("StateCommitment")
102-
batch := b.database.NewIndexedBatch() // this is a hack because we don't need to write to the db
102+
batch, closer := b.database.NewSnapshotBatch() // this is a hack because we don't need to write to the db
103+
defer closer()
103104
return core.NewState(batch).Commitment()
104105
}
105106

@@ -116,8 +117,9 @@ func (b *Blockchain) Head() (*core.Block, error) {
116117
return nil, err
117118
}
118119

119-
txn := b.database.NewIndexedBatch()
120-
return core.GetBlockByNumber(txn, curHeight)
120+
snapshot := b.database.NewSnapshot()
121+
defer snapshot.Close()
122+
return core.GetBlockByNumber(snapshot, curHeight)
121123
}
122124

123125
func (b *Blockchain) HeadsHeader() (*core.Header, error) {
@@ -141,8 +143,9 @@ func headsHeader(txn db.KeyValueReader) (*core.Header, error) {
141143

142144
func (b *Blockchain) BlockByNumber(number uint64) (*core.Block, error) {
143145
b.listener.OnRead("BlockByNumber")
144-
txn := b.database.NewIndexedBatch()
145-
return core.GetBlockByNumber(txn, number)
146+
snapshot := b.database.NewSnapshot()
147+
defer snapshot.Close()
148+
return core.GetBlockByNumber(snapshot, number)
146149
}
147150

148151
func (b *Blockchain) BlockHeaderByNumber(number uint64) (*core.Header, error) {
@@ -157,8 +160,9 @@ func (b *Blockchain) BlockByHash(hash *felt.Felt) (*core.Block, error) {
157160
return nil, err
158161
}
159162

160-
txn := b.database.NewIndexedBatch()
161-
return core.GetBlockByNumber(txn, blockNum)
163+
snapshot := b.database.NewSnapshot()
164+
defer snapshot.Close()
165+
return core.GetBlockByNumber(snapshot, blockNum)
162166
}
163167

164168
func (b *Blockchain) BlockHeaderByHash(hash *felt.Felt) (*core.Header, error) {
@@ -244,48 +248,51 @@ func (b *Blockchain) Store(
244248
stateUpdate *core.StateUpdate,
245249
newClasses map[felt.Felt]core.ClassDefinition,
246250
) error {
247-
err := b.database.Update(func(txn db.IndexedBatch) error {
248-
if err := verifyBlock(txn, block); err != nil {
249-
return err
250-
}
251-
252-
if err := core.NewState(txn).Update(block.Number, stateUpdate, newClasses, false); err != nil {
253-
return err
254-
}
255-
if err := core.WriteBlockHeader(txn, block.Header); err != nil {
256-
return err
257-
}
251+
txn, closer := b.database.NewSnapshotBatch()
252+
defer closer()
253+
if err := verifyBlock(txn, block); err != nil {
254+
return err
255+
}
258256

259-
for i, tx := range block.Transactions {
260-
if err := core.WriteTxAndReceipt(txn, block.Number, uint64(i), tx,
261-
block.Receipts[i]); err != nil {
262-
return err
263-
}
264-
}
257+
if err := core.NewState(txn).Update(block.Number, stateUpdate, newClasses, false); err != nil {
258+
return err
259+
}
260+
if err := core.WriteBlockHeader(txn, block.Header); err != nil {
261+
return err
262+
}
265263

266-
if err := core.WriteStateUpdateByBlockNum(txn, block.Number, stateUpdate); err != nil {
264+
for i, tx := range block.Transactions {
265+
if err := core.WriteTxAndReceipt(txn, block.Number, uint64(i), tx,
266+
block.Receipts[i]); err != nil {
267267
return err
268268
}
269+
}
269270

270-
if err := core.WriteBlockCommitment(txn, block.Number, blockCommitments); err != nil {
271-
return err
272-
}
271+
if err := core.WriteStateUpdateByBlockNum(txn, block.Number, stateUpdate); err != nil {
272+
return err
273+
}
273274

274-
if err := core.WriteL1HandlerMsgHashes(txn, block.Transactions); err != nil {
275-
return err
276-
}
275+
if err := core.WriteBlockCommitment(txn, block.Number, blockCommitments); err != nil {
276+
return err
277+
}
277278

278-
err := storeCasmClassHashesV2ForBlock(txn, block.ProtocolVersion, newClasses, stateUpdate)
279-
if err != nil {
280-
return err
281-
}
279+
if err := core.WriteL1HandlerMsgHashes(txn, block.Transactions); err != nil {
280+
return err
281+
}
282282

283-
return core.WriteChainHeight(txn, block.Number)
284-
})
283+
err := storeCasmClassHashesV2ForBlock(txn, block.ProtocolVersion, newClasses, stateUpdate)
285284
if err != nil {
286285
return err
287286
}
288287

288+
if err := core.WriteChainHeight(txn, block.Number); err != nil {
289+
return err
290+
}
291+
292+
if err := txn.Write(); err != nil {
293+
return err
294+
}
295+
289296
return b.runningFilter.Insert(
290297
block.EventsBloom,
291298
block.Number,
@@ -296,7 +303,7 @@ func (b *Blockchain) Store(
296303
// For versions < 0.14.1, it computes hashes from class definitions.
297304
// For versions >= 0.14.1, it uses pre-computed hashes from the state update.
298305
func storeCasmClassHashesV2ForBlock(
299-
txn db.IndexedBatch,
306+
txn db.KeyValueWriter,
300307
protocolVersion string,
301308
newClasses map[felt.Felt]core.ClassDefinition,
302309
stateUpdate *core.StateUpdate,
@@ -315,7 +322,7 @@ func storeCasmClassHashesV2ForBlock(
315322

316323
// computeAndStoreCasmClassHashesV2 computes and stores CASM class hashes V2 from class definitions.
317324
func computeAndStoreCasmClassHashesV2(
318-
txn db.IndexedBatch,
325+
txn db.KeyValueWriter,
319326
declaredClasses map[felt.Felt]core.ClassDefinition,
320327
) error {
321328
for classHash, classDefinition := range declaredClasses {
@@ -336,7 +343,7 @@ func computeAndStoreCasmClassHashesV2(
336343

337344
// storeCasmClassHashesV2 stores pre-computed CASM class hashes V2 from the state update.
338345
func storeCasmClassHashesV2(
339-
txn db.IndexedBatch,
346+
txn db.KeyValueWriter,
340347
declaredV1Classes map[felt.Felt]*felt.Felt,
341348
) error {
342349
for classHash, casmClassHashV2 := range declaredV1Classes {
@@ -405,33 +412,32 @@ func (b *Blockchain) SanityCheckNewHeight(block *core.Block, stateUpdate *core.S
405412

406413
type StateCloser = func() error
407414

408-
var noopStateCloser = func() error { return nil } // TODO: remove this once we refactor the state
409-
410415
// HeadState returns a StateReader that provides a stable view to the latest state
411416
func (b *Blockchain) HeadState() (core.StateReader, StateCloser, error) {
412417
b.listener.OnRead("HeadState")
413-
txn := b.database.NewIndexedBatch()
418+
snapshot := b.database.NewSnapshot()
414419

415-
_, err := core.GetChainHeight(txn)
420+
_, err := core.GetChainHeight(snapshot)
416421
if err != nil {
417422
return nil, nil, err
418423
}
419424

420-
return core.NewState(txn), noopStateCloser, nil
425+
return core.NewStateSnapshotReader(snapshot), snapshot.Close, nil
421426
}
422427

423428
// StateAtBlockNumber returns a StateReader that provides
424429
// a stable view to the state at the given block number
425430
func (b *Blockchain) StateAtBlockNumber(blockNumber uint64) (core.StateReader, StateCloser, error) {
426431
b.listener.OnRead("StateAtBlockNumber")
427-
txn := b.database.NewIndexedBatch()
432+
snapshot := b.database.NewSnapshot()
428433

429-
_, err := core.GetBlockHeaderByNumber(txn, blockNumber)
434+
_, err := core.GetBlockHeaderByNumber(snapshot, blockNumber)
430435
if err != nil {
431436
return nil, nil, err
432437
}
433438

434-
return core.NewDeprecatedStateHistory(core.NewState(txn), blockNumber), noopStateCloser, nil
439+
stateReader := core.NewStateSnapshotReader(snapshot)
440+
return core.NewDeprecatedStateHistory(stateReader, blockNumber), snapshot.Close, nil
435441
}
436442

437443
// StateAtBlockHash returns a StateReader that provides
@@ -440,18 +446,19 @@ func (b *Blockchain) StateAtBlockHash(blockHash *felt.Felt) (core.StateReader, S
440446
b.listener.OnRead("StateAtBlockHash")
441447
if blockHash.IsZero() {
442448
memDB := memory.New()
443-
txn := memDB.NewIndexedBatch()
444-
emptyState := core.NewState(txn)
445-
return emptyState, noopStateCloser, nil
449+
snapshot := memDB.NewSnapshot()
450+
emptyState := core.NewStateSnapshotReader(snapshot)
451+
return emptyState, snapshot.Close, nil
446452
}
447453

448-
txn := b.database.NewIndexedBatch()
449-
header, err := core.GetBlockHeaderByHash(txn, blockHash)
454+
snapshot := b.database.NewSnapshot()
455+
header, err := core.GetBlockHeaderByHash(snapshot, blockHash)
450456
if err != nil {
451457
return nil, nil, err
452458
}
453459

454-
return core.NewDeprecatedStateHistory(core.NewState(txn), header.Number), noopStateCloser, nil
460+
stateReader := core.NewStateSnapshotReader(snapshot)
461+
return core.NewDeprecatedStateHistory(stateReader, header.Number), snapshot.Close, nil
455462
}
456463

457464
// EventFilter returns an EventFilter object that is tied to a snapshot of the blockchain
@@ -480,25 +487,34 @@ func (b *Blockchain) EventFilter(
480487

481488
// RevertHead reverts the head block
482489
func (b *Blockchain) RevertHead() error {
483-
return b.database.Update(b.revertHead)
490+
txn, closer := b.database.NewSnapshotBatch()
491+
defer closer()
492+
if err := b.revertHead(txn); err != nil {
493+
return err
494+
}
495+
if err := txn.Write(); err != nil {
496+
return err
497+
}
498+
return nil
484499
}
485500

486501
// todo(rdr): return `core.StateDiff` by value
487502
func (b *Blockchain) GetReverseStateDiff() (*core.StateDiff, error) {
488503
var reverseStateDiff *core.StateDiff
489504

490-
txn := b.database.NewIndexedBatch()
491-
blockNum, err := core.GetChainHeight(txn)
505+
snapshot := b.database.NewSnapshot()
506+
defer snapshot.Close()
507+
blockNum, err := core.GetChainHeight(snapshot)
492508
if err != nil {
493509
return nil, err
494510
}
495511

496-
stateUpdate, err := core.GetStateUpdateByBlockNum(txn, blockNum)
512+
stateUpdate, err := core.GetStateUpdateByBlockNum(snapshot, blockNum)
497513
if err != nil {
498514
return nil, err
499515
}
500516

501-
state := core.NewState(txn)
517+
state := core.NewStateSnapshotReader(snapshot)
502518
reverseStateDiff, err = state.GetReverseStateDiff(blockNum, stateUpdate.StateDiff)
503519
if err != nil {
504520
return nil, err
@@ -507,7 +523,7 @@ func (b *Blockchain) GetReverseStateDiff() (*core.StateDiff, error) {
507523
return reverseStateDiff, nil
508524
}
509525

510-
func (b *Blockchain) revertHead(txn db.IndexedBatch) error {
526+
func (b *Blockchain) revertHead(txn db.SnapshotBatch) error {
511527
blockNumber, err := core.GetChainHeight(txn)
512528
if err != nil {
513529
return err
@@ -579,8 +595,8 @@ func (b *Blockchain) Simulate(
579595
sign utils.BlockSignFunc,
580596
) (SimulateResult, error) {
581597
// Simulate without commit
582-
txn := b.database.NewIndexedBatch()
583-
defer txn.Reset()
598+
txn, closer := b.database.NewSnapshotBatch()
599+
defer closer()
584600

585601
if err := b.updateStateRoots(txn, block, stateUpdate, newClasses); err != nil {
586602
return SimulateResult{}, err
@@ -615,38 +631,41 @@ func (b *Blockchain) Finalise(
615631
newClasses map[felt.Felt]core.ClassDefinition,
616632
sign utils.BlockSignFunc,
617633
) error {
618-
err := b.database.Update(func(txn db.IndexedBatch) error {
619-
if err := b.updateStateRoots(txn, block, stateUpdate, newClasses); err != nil {
620-
return err
621-
}
622-
commitments, err := b.updateBlockHash(block, stateUpdate)
623-
if err != nil {
624-
return err
625-
}
626-
if err := b.signBlock(block, stateUpdate, sign); err != nil {
627-
return err
628-
}
629-
if err := b.storeBlockData(txn, block, stateUpdate, commitments); err != nil {
630-
return err
631-
}
632-
633-
err = storeCasmClassHashesV2ForBlock(txn, block.ProtocolVersion, newClasses, stateUpdate)
634-
if err != nil {
635-
return err
636-
}
634+
txn, closer := b.database.NewSnapshotBatch()
635+
defer closer()
636+
if err := b.updateStateRoots(txn, block, stateUpdate, newClasses); err != nil {
637+
return err
638+
}
639+
commitments, err := b.updateBlockHash(block, stateUpdate)
640+
if err != nil {
641+
return err
642+
}
643+
if err := b.signBlock(block, stateUpdate, sign); err != nil {
644+
return err
645+
}
646+
if err := b.storeBlockData(txn, block, stateUpdate, commitments); err != nil {
647+
return err
648+
}
637649

638-
return core.WriteChainHeight(txn, block.Number)
639-
})
650+
err = storeCasmClassHashesV2ForBlock(txn, block.ProtocolVersion, newClasses, stateUpdate)
640651
if err != nil {
641652
return err
642653
}
643654

655+
if err := core.WriteChainHeight(txn, block.Number); err != nil {
656+
return err
657+
}
658+
659+
if err := txn.Write(); err != nil {
660+
return err
661+
}
662+
644663
return b.runningFilter.Insert(block.EventsBloom, block.Number)
645664
}
646665

647666
// updateStateRoots computes and updates state roots in the block and state update
648667
func (b *Blockchain) updateStateRoots(
649-
txn db.IndexedBatch,
668+
txn db.SnapshotBatch,
650669
block *core.Block,
651670
stateUpdate *core.StateUpdate,
652671
newClasses map[felt.Felt]core.ClassDefinition,
@@ -715,7 +734,7 @@ func (b *Blockchain) signBlock(
715734

716735
// storeBlockData persists all block-related data to the database
717736
func (b *Blockchain) storeBlockData(
718-
txn db.IndexedBatch,
737+
txn db.SnapshotBatch,
719738
block *core.Block,
720739
stateUpdate *core.StateUpdate,
721740
commitments *core.BlockCommitments,

0 commit comments

Comments
 (0)