Skip to content

Commit cfb7f5a

Browse files
committed
Integrate the snapshotbatch with Juno
1 parent fa90bb4 commit cfb7f5a

File tree

13 files changed

+406
-101
lines changed

13 files changed

+406
-101
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) {
@@ -236,48 +240,51 @@ func (b *Blockchain) Store(
236240
stateUpdate *core.StateUpdate,
237241
newClasses map[felt.Felt]core.ClassDefinition,
238242
) error {
239-
err := b.database.Update(func(txn db.IndexedBatch) error {
240-
if err := verifyBlock(txn, block); err != nil {
241-
return err
242-
}
243-
244-
if err := core.NewState(txn).Update(block.Number, stateUpdate, newClasses, false); err != nil {
245-
return err
246-
}
247-
if err := core.WriteBlockHeader(txn, block.Header); err != nil {
248-
return err
249-
}
243+
txn, closer := b.database.NewSnapshotBatch()
244+
defer closer()
245+
if err := verifyBlock(txn, block); err != nil {
246+
return err
247+
}
250248

251-
for i, tx := range block.Transactions {
252-
if err := core.WriteTxAndReceipt(txn, block.Number, uint64(i), tx,
253-
block.Receipts[i]); err != nil {
254-
return err
255-
}
256-
}
249+
if err := core.NewState(txn).Update(block.Number, stateUpdate, newClasses, false); err != nil {
250+
return err
251+
}
252+
if err := core.WriteBlockHeader(txn, block.Header); err != nil {
253+
return err
254+
}
257255

258-
if err := core.WriteStateUpdateByBlockNum(txn, block.Number, stateUpdate); err != nil {
256+
for i, tx := range block.Transactions {
257+
if err := core.WriteTxAndReceipt(txn, block.Number, uint64(i), tx,
258+
block.Receipts[i]); err != nil {
259259
return err
260260
}
261+
}
261262

262-
if err := core.WriteBlockCommitment(txn, block.Number, blockCommitments); err != nil {
263-
return err
264-
}
263+
if err := core.WriteStateUpdateByBlockNum(txn, block.Number, stateUpdate); err != nil {
264+
return err
265+
}
265266

266-
if err := core.WriteL1HandlerMsgHashes(txn, block.Transactions); err != nil {
267-
return err
268-
}
267+
if err := core.WriteBlockCommitment(txn, block.Number, blockCommitments); err != nil {
268+
return err
269+
}
269270

270-
err := storeCasmClassHashesV2ForBlock(txn, block.ProtocolVersion, newClasses, stateUpdate)
271-
if err != nil {
272-
return err
273-
}
271+
if err := core.WriteL1HandlerMsgHashes(txn, block.Transactions); err != nil {
272+
return err
273+
}
274274

275-
return core.WriteChainHeight(txn, block.Number)
276-
})
275+
err := storeCasmClassHashesV2ForBlock(txn, block.ProtocolVersion, newClasses, stateUpdate)
277276
if err != nil {
278277
return err
279278
}
280279

280+
if err := core.WriteChainHeight(txn, block.Number); err != nil {
281+
return err
282+
}
283+
284+
if err := txn.Write(); err != nil {
285+
return err
286+
}
287+
281288
return b.runningFilter.Insert(
282289
block.EventsBloom,
283290
block.Number,
@@ -288,7 +295,7 @@ func (b *Blockchain) Store(
288295
// For versions < 0.14.1, it computes hashes from class definitions.
289296
// For versions >= 0.14.1, it uses pre-computed hashes from the state update.
290297
func storeCasmClassHashesV2ForBlock(
291-
txn db.IndexedBatch,
298+
txn db.KeyValueWriter,
292299
protocolVersion string,
293300
newClasses map[felt.Felt]core.ClassDefinition,
294301
stateUpdate *core.StateUpdate,
@@ -307,7 +314,7 @@ func storeCasmClassHashesV2ForBlock(
307314

308315
// computeAndStoreCasmClassHashesV2 computes and stores CASM class hashes V2 from class definitions.
309316
func computeAndStoreCasmClassHashesV2(
310-
txn db.IndexedBatch,
317+
txn db.KeyValueWriter,
311318
declaredClasses map[felt.Felt]core.ClassDefinition,
312319
) error {
313320
for classHash, classDefinition := range declaredClasses {
@@ -328,7 +335,7 @@ func computeAndStoreCasmClassHashesV2(
328335

329336
// storeCasmClassHashesV2 stores pre-computed CASM class hashes V2 from the state update.
330337
func storeCasmClassHashesV2(
331-
txn db.IndexedBatch,
338+
txn db.KeyValueWriter,
332339
declaredV1Classes map[felt.Felt]*felt.Felt,
333340
) error {
334341
for classHash, casmClassHashV2 := range declaredV1Classes {
@@ -397,33 +404,32 @@ func (b *Blockchain) SanityCheckNewHeight(block *core.Block, stateUpdate *core.S
397404

398405
type StateCloser = func() error
399406

400-
var noopStateCloser = func() error { return nil } // TODO: remove this once we refactor the state
401-
402407
// HeadState returns a StateReader that provides a stable view to the latest state
403408
func (b *Blockchain) HeadState() (core.StateReader, StateCloser, error) {
404409
b.listener.OnRead("HeadState")
405-
txn := b.database.NewIndexedBatch()
410+
snapshot := b.database.NewSnapshot()
406411

407-
_, err := core.GetChainHeight(txn)
412+
_, err := core.GetChainHeight(snapshot)
408413
if err != nil {
409414
return nil, nil, err
410415
}
411416

412-
return core.NewState(txn), noopStateCloser, nil
417+
return core.NewStateSnapshotReader(snapshot), snapshot.Close, nil
413418
}
414419

415420
// StateAtBlockNumber returns a StateReader that provides a stable view to the state at the given
416421
// block number
417422
func (b *Blockchain) StateAtBlockNumber(blockNumber uint64) (core.StateReader, StateCloser, error) {
418423
b.listener.OnRead("StateAtBlockNumber")
419-
txn := b.database.NewIndexedBatch()
424+
snapshot := b.database.NewSnapshot()
420425

421-
_, err := core.GetBlockHeaderByNumber(txn, blockNumber)
426+
_, err := core.GetBlockHeaderByNumber(snapshot, blockNumber)
422427
if err != nil {
423428
return nil, nil, err
424429
}
425430

426-
return core.NewDeprecatedStateHistory(core.NewState(txn), blockNumber), noopStateCloser, nil
431+
stateReader := core.NewStateSnapshotReader(snapshot)
432+
return core.NewDeprecatedStateHistory(stateReader, blockNumber), snapshot.Close, nil
427433
}
428434

429435
// StateAtBlockHash returns a StateReader that provides a stable view to the state at the given
@@ -432,18 +438,19 @@ func (b *Blockchain) StateAtBlockHash(blockHash *felt.Felt) (core.StateReader, S
432438
b.listener.OnRead("StateAtBlockHash")
433439
if blockHash.IsZero() {
434440
memDB := memory.New()
435-
txn := memDB.NewIndexedBatch()
436-
emptyState := core.NewState(txn)
437-
return emptyState, noopStateCloser, nil
441+
snapshot := memDB.NewSnapshot()
442+
emptyState := core.NewStateSnapshotReader(snapshot)
443+
return emptyState, snapshot.Close, nil
438444
}
439445

440-
txn := b.database.NewIndexedBatch()
441-
header, err := core.GetBlockHeaderByHash(txn, blockHash)
446+
snapshot := b.database.NewSnapshot()
447+
header, err := core.GetBlockHeaderByHash(snapshot, blockHash)
442448
if err != nil {
443449
return nil, nil, err
444450
}
445451

446-
return core.NewDeprecatedStateHistory(core.NewState(txn), header.Number), noopStateCloser, nil
452+
stateReader := core.NewStateSnapshotReader(snapshot)
453+
return core.NewDeprecatedStateHistory(stateReader, header.Number), snapshot.Close, nil
447454
}
448455

449456
// EventFilter returns an EventFilter object that is tied to a snapshot of the blockchain
@@ -472,25 +479,34 @@ func (b *Blockchain) EventFilter(
472479

473480
// RevertHead reverts the head block
474481
func (b *Blockchain) RevertHead() error {
475-
return b.database.Update(b.revertHead)
482+
txn, closer := b.database.NewSnapshotBatch()
483+
defer closer()
484+
if err := b.revertHead(txn); err != nil {
485+
return err
486+
}
487+
if err := txn.Write(); err != nil {
488+
return err
489+
}
490+
return nil
476491
}
477492

478493
// todo(rdr): return `core.StateDiff` by value
479494
func (b *Blockchain) GetReverseStateDiff() (*core.StateDiff, error) {
480495
var reverseStateDiff *core.StateDiff
481496

482-
txn := b.database.NewIndexedBatch()
483-
blockNum, err := core.GetChainHeight(txn)
497+
snapshot := b.database.NewSnapshot()
498+
defer snapshot.Close()
499+
blockNum, err := core.GetChainHeight(snapshot)
484500
if err != nil {
485501
return nil, err
486502
}
487503

488-
stateUpdate, err := core.GetStateUpdateByBlockNum(txn, blockNum)
504+
stateUpdate, err := core.GetStateUpdateByBlockNum(snapshot, blockNum)
489505
if err != nil {
490506
return nil, err
491507
}
492508

493-
state := core.NewState(txn)
509+
state := core.NewStateSnapshotReader(snapshot)
494510
reverseStateDiff, err = state.GetReverseStateDiff(blockNum, stateUpdate.StateDiff)
495511
if err != nil {
496512
return nil, err
@@ -499,7 +515,7 @@ func (b *Blockchain) GetReverseStateDiff() (*core.StateDiff, error) {
499515
return reverseStateDiff, nil
500516
}
501517

502-
func (b *Blockchain) revertHead(txn db.IndexedBatch) error {
518+
func (b *Blockchain) revertHead(txn db.SnapshotBatch) error {
503519
blockNumber, err := core.GetChainHeight(txn)
504520
if err != nil {
505521
return err
@@ -571,8 +587,8 @@ func (b *Blockchain) Simulate(
571587
sign utils.BlockSignFunc,
572588
) (SimulateResult, error) {
573589
// Simulate without commit
574-
txn := b.database.NewIndexedBatch()
575-
defer txn.Reset()
590+
txn, closer := b.database.NewSnapshotBatch()
591+
defer closer()
576592

577593
if err := b.updateStateRoots(txn, block, stateUpdate, newClasses); err != nil {
578594
return SimulateResult{}, err
@@ -607,38 +623,41 @@ func (b *Blockchain) Finalise(
607623
newClasses map[felt.Felt]core.ClassDefinition,
608624
sign utils.BlockSignFunc,
609625
) error {
610-
err := b.database.Update(func(txn db.IndexedBatch) error {
611-
if err := b.updateStateRoots(txn, block, stateUpdate, newClasses); err != nil {
612-
return err
613-
}
614-
commitments, err := b.updateBlockHash(block, stateUpdate)
615-
if err != nil {
616-
return err
617-
}
618-
if err := b.signBlock(block, stateUpdate, sign); err != nil {
619-
return err
620-
}
621-
if err := b.storeBlockData(txn, block, stateUpdate, commitments); err != nil {
622-
return err
623-
}
624-
625-
err = storeCasmClassHashesV2ForBlock(txn, block.ProtocolVersion, newClasses, stateUpdate)
626-
if err != nil {
627-
return err
628-
}
626+
txn, closer := b.database.NewSnapshotBatch()
627+
defer closer()
628+
if err := b.updateStateRoots(txn, block, stateUpdate, newClasses); err != nil {
629+
return err
630+
}
631+
commitments, err := b.updateBlockHash(block, stateUpdate)
632+
if err != nil {
633+
return err
634+
}
635+
if err := b.signBlock(block, stateUpdate, sign); err != nil {
636+
return err
637+
}
638+
if err := b.storeBlockData(txn, block, stateUpdate, commitments); err != nil {
639+
return err
640+
}
629641

630-
return core.WriteChainHeight(txn, block.Number)
631-
})
642+
err = storeCasmClassHashesV2ForBlock(txn, block.ProtocolVersion, newClasses, stateUpdate)
632643
if err != nil {
633644
return err
634645
}
635646

647+
if err := core.WriteChainHeight(txn, block.Number); err != nil {
648+
return err
649+
}
650+
651+
if err := txn.Write(); err != nil {
652+
return err
653+
}
654+
636655
return b.runningFilter.Insert(block.EventsBloom, block.Number)
637656
}
638657

639658
// updateStateRoots computes and updates state roots in the block and state update
640659
func (b *Blockchain) updateStateRoots(
641-
txn db.IndexedBatch,
660+
txn db.SnapshotBatch,
642661
block *core.Block,
643662
stateUpdate *core.StateUpdate,
644663
newClasses map[felt.Felt]core.ClassDefinition,
@@ -707,7 +726,7 @@ func (b *Blockchain) signBlock(
707726

708727
// storeBlockData persists all block-related data to the database
709728
func (b *Blockchain) storeBlockData(
710-
txn db.IndexedBatch,
729+
txn db.SnapshotBatch,
711730
block *core.Block,
712731
stateUpdate *core.StateUpdate,
713732
commitments *core.BlockCommitments,

core/accessors.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ func GetReceiptsByBlockNum(iterable db.Iterable, blockNum uint64) ([]*Transactio
471471
return receipts, nil
472472
}
473473

474-
func GetBlockByNumber(r db.IndexedBatch, blockNum uint64) (*Block, error) {
474+
func GetBlockByNumber(r db.KeyValueReader, blockNum uint64) (*Block, error) {
475475
header, err := GetBlockHeaderByNumber(r, blockNum)
476476
if err != nil {
477477
return nil, err

0 commit comments

Comments
 (0)