Skip to content

Commit 5e561f5

Browse files
authored
cache receipts in workingset (iotexproject#2360)
* cache receipts in workingset
1 parent 8230090 commit 5e561f5

File tree

3 files changed

+61
-35
lines changed

3 files changed

+61
-35
lines changed

state/factory/factory.go

+15-6
Original file line numberDiff line numberDiff line change
@@ -442,13 +442,17 @@ func (sf *factory) Validate(ctx context.Context, blk *block.Block) error {
442442
if err != nil {
443443
return err
444444
}
445-
if isExist {
446-
return nil
445+
if !isExist {
446+
if err := ws.ValidateBlock(ctx, blk); err != nil {
447+
return errors.Wrap(err, "failed to validate block with workingset in factory")
448+
}
449+
sf.putIntoWorkingSets(key, ws)
447450
}
448-
if err := ws.ValidateBlock(ctx, blk); err != nil {
449-
return errors.Wrap(err, "failed to validate block with workingset in factory")
451+
receipts, err := ws.Receipts()
452+
if err != nil {
453+
return err
450454
}
451-
sf.putIntoWorkingSets(key, ws)
455+
blk.Receipts = receipts
452456
return nil
453457
}
454458

@@ -540,7 +544,7 @@ func (sf *factory) PutBlock(ctx context.Context, blk *block.Block) error {
540544
if !sf.skipBlockValidationOnPut {
541545
err = ws.ValidateBlock(ctx, blk)
542546
} else {
543-
_, err = ws.Process(ctx, blk.RunnableActions().Actions())
547+
err = ws.Process(ctx, blk.RunnableActions().Actions())
544548
}
545549
if err != nil {
546550
log.L().Error("Failed to update state.", zap.Error(err))
@@ -549,6 +553,11 @@ func (sf *factory) PutBlock(ctx context.Context, blk *block.Block) error {
549553
}
550554
sf.mutex.Lock()
551555
defer sf.mutex.Unlock()
556+
receipts, err := ws.Receipts()
557+
if err != nil {
558+
return err
559+
}
560+
blk.Receipts = receipts
552561
h, _ := ws.Height()
553562
if sf.currentChainHeight+1 != h {
554563
// another working set with correct version already committed, do nothing

state/factory/statedb.go

+15-6
Original file line numberDiff line numberDiff line change
@@ -269,13 +269,17 @@ func (sdb *stateDB) Validate(ctx context.Context, blk *block.Block) error {
269269
if err != nil {
270270
return err
271271
}
272-
if isExist {
273-
return nil
272+
if !isExist {
273+
if err = ws.ValidateBlock(ctx, blk); err != nil {
274+
return errors.Wrap(err, "failed to validate block with workingset in statedb")
275+
}
276+
sdb.putIntoWorkingSets(key, ws)
274277
}
275-
if err = ws.ValidateBlock(ctx, blk); err != nil {
276-
return errors.Wrap(err, "failed to validate block with workingset in statedb")
278+
receipts, err := ws.Receipts()
279+
if err != nil {
280+
return err
277281
}
278-
sdb.putIntoWorkingSets(key, ws)
282+
blk.Receipts = receipts
279283
return nil
280284
}
281285

@@ -366,7 +370,7 @@ func (sdb *stateDB) PutBlock(ctx context.Context, blk *block.Block) error {
366370
if !sdb.skipBlockValidationOnPut {
367371
err = ws.ValidateBlock(ctx, blk)
368372
} else {
369-
_, err = ws.Process(ctx, blk.RunnableActions().Actions())
373+
err = ws.Process(ctx, blk.RunnableActions().Actions())
370374
}
371375
if err != nil {
372376
log.L().Error("Failed to update state.", zap.Error(err))
@@ -375,6 +379,11 @@ func (sdb *stateDB) PutBlock(ctx context.Context, blk *block.Block) error {
375379
}
376380
sdb.mutex.Lock()
377381
defer sdb.mutex.Unlock()
382+
receipts, err := ws.Receipts()
383+
if err != nil {
384+
return err
385+
}
386+
blk.Receipts = receipts
378387
h, _ := ws.Height()
379388
if sdb.currentChainHeight+1 != h {
380389
// another working set with correct version already committed, do nothing

state/factory/workingset.go

+31-23
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ type (
4646
height uint64
4747
finalized bool
4848
dock protocol.Dock
49+
receipts []*action.Receipt
4950
commitFunc func(uint64) error
5051
readviewFunc func(name string) (uint64, interface{}, error)
5152
writeviewFunc func(name string, v interface{}) error
@@ -72,6 +73,13 @@ func (ws *workingSet) digest() (hash.Hash256, error) {
7273
return ws.digestFunc(), nil
7374
}
7475

76+
func (ws *workingSet) Receipts() ([]*action.Receipt, error) {
77+
if !ws.finalized {
78+
return nil, errors.New("workingset has not been finalized yet")
79+
}
80+
return ws.receipts, nil
81+
}
82+
7583
// Height returns the Height of the block being worked on
7684
func (ws *workingSet) Height() (uint64, error) {
7785
return ws.height, nil
@@ -316,50 +324,51 @@ func (ws *workingSet) validateNonce(blk *block.Block) error {
316324
return nil
317325
}
318326

319-
func (ws *workingSet) Process(ctx context.Context, actions []action.SealedEnvelope) ([]*action.Receipt, error) {
327+
func (ws *workingSet) Process(ctx context.Context, actions []action.SealedEnvelope) error {
320328
return ws.process(ctx, actions)
321329
}
322330

323-
func (ws *workingSet) process(ctx context.Context, actions []action.SealedEnvelope) ([]*action.Receipt, error) {
331+
func (ws *workingSet) process(ctx context.Context, actions []action.SealedEnvelope) error {
324332
var err error
325333
reg := protocol.MustGetRegistry(ctx)
326334
for _, act := range actions {
327335
if ctx, err = withActionCtx(ctx, act); err != nil {
328-
return nil, err
336+
return err
329337
}
330338
for _, p := range reg.All() {
331339
if validator, ok := p.(protocol.ActionValidator); ok {
332340
if err := validator.Validate(ctx, act.Action(), ws); err != nil {
333-
return nil, err
341+
return err
334342
}
335343
}
336344
}
337345
}
338346
for _, p := range protocol.MustGetRegistry(ctx).All() {
339347
if pp, ok := p.(protocol.PreStatesCreator); ok {
340348
if err := pp.CreatePreStates(ctx, ws); err != nil {
341-
return nil, err
349+
return err
342350
}
343351
}
344352
}
345353
// TODO: verify whether the post system actions are appended tail
346354

347355
receipts, err := ws.runActions(ctx, actions)
348356
if err != nil {
349-
return nil, err
357+
return err
350358
}
351-
return receipts, ws.finalize()
359+
ws.receipts = receipts
360+
return ws.finalize()
352361
}
353362

354363
func (ws *workingSet) pickAndRunActions(
355364
ctx context.Context,
356365
ap actpool.ActPool,
357366
postSystemActions []action.SealedEnvelope,
358367
allowedBlockGasResidue uint64,
359-
) ([]*action.Receipt, []action.SealedEnvelope, error) {
368+
) ([]action.SealedEnvelope, error) {
360369
err := ws.validate(ctx)
361370
if err != nil {
362-
return nil, nil, err
371+
return nil, err
363372
}
364373
receipts := make([]*action.Receipt, 0)
365374
executedActions := make([]action.SealedEnvelope, 0)
@@ -368,7 +377,7 @@ func (ws *workingSet) pickAndRunActions(
368377
for _, p := range reg.All() {
369378
if pp, ok := p.(protocol.PreStatesCreator); ok {
370379
if err := pp.CreatePreStates(ctx, ws); err != nil {
371-
return nil, nil, err
380+
return nil, err
372381
}
373382
}
374383
}
@@ -398,7 +407,7 @@ func (ws *workingSet) pickAndRunActions(
398407
if err != nil {
399408
caller, err := address.FromBytes(nextAction.SrcPubkey().Hash())
400409
if err != nil {
401-
return nil, nil, err
410+
return nil, err
402411
}
403412
ap.DeleteAction(caller)
404413
actionIterator.PopAccount()
@@ -412,7 +421,7 @@ func (ws *workingSet) pickAndRunActions(
412421
actionIterator.PopAccount()
413422
continue
414423
default:
415-
return nil, nil, errors.Wrapf(err, "Failed to update state changes for selp %x", nextAction.Hash())
424+
return nil, errors.Wrapf(err, "Failed to update state changes for selp %x", nextAction.Hash())
416425
}
417426
if receipt != nil {
418427
blkCtx.GasLimit -= receipt.GasConsumed
@@ -431,27 +440,27 @@ func (ws *workingSet) pickAndRunActions(
431440

432441
for _, selp := range postSystemActions {
433442
if ctx, err = withActionCtx(ctx, selp); err != nil {
434-
return nil, nil, err
443+
return nil, err
435444
}
436445
receipt, err := ws.runAction(ctx, selp)
437446
if err != nil {
438-
return nil, nil, err
447+
return nil, err
439448
}
440449
if receipt != nil {
441450
receipts = append(receipts, receipt)
442451
}
443452
executedActions = append(executedActions, selp)
444453
}
454+
ws.receipts = receipts
445455

446-
return receipts, executedActions, ws.finalize()
456+
return executedActions, ws.finalize()
447457
}
448458

449459
func (ws *workingSet) ValidateBlock(ctx context.Context, blk *block.Block) error {
450460
if err := ws.validateNonce(blk); err != nil {
451461
return errors.Wrap(err, "failed to validate nonce")
452462
}
453-
receipts, err := ws.process(ctx, blk.RunnableActions().Actions())
454-
if err != nil {
463+
if err := ws.process(ctx, blk.RunnableActions().Actions()); err != nil {
455464
log.L().Error("Failed to update state.", zap.Uint64("height", ws.height), zap.Error(err))
456465
return err
457466
}
@@ -463,11 +472,10 @@ func (ws *workingSet) ValidateBlock(ctx context.Context, blk *block.Block) error
463472
if err = blk.VerifyDeltaStateDigest(digest); err != nil {
464473
return errors.Wrap(err, "failed to verify delta state digest")
465474
}
466-
if err = blk.VerifyReceiptRoot(calculateReceiptRoot(receipts)); err != nil {
475+
if err = blk.VerifyReceiptRoot(calculateReceiptRoot(ws.receipts)); err != nil {
467476
return errors.Wrap(err, "Failed to verify receipt root")
468477
}
469478

470-
blk.Receipts = receipts
471479
return nil
472480
}
473481

@@ -477,7 +485,7 @@ func (ws *workingSet) CreateBuilder(
477485
postSystemActions []action.SealedEnvelope,
478486
allowedBlockGasResidue uint64,
479487
) (*block.Builder, error) {
480-
rc, actions, err := ws.pickAndRunActions(ctx, ap, postSystemActions, allowedBlockGasResidue)
488+
actions, err := ws.pickAndRunActions(ctx, ap, postSystemActions, allowedBlockGasResidue)
481489
if err != nil {
482490
return nil, err
483491
}
@@ -504,8 +512,8 @@ func (ws *workingSet) CreateBuilder(
504512
SetTimestamp(blkCtx.BlockTimeStamp).
505513
SetPrevBlockHash(prevBlkHash).
506514
SetDeltaStateDigest(digest).
507-
SetReceipts(rc).
508-
SetReceiptRoot(calculateReceiptRoot(rc)).
509-
SetLogsBloom(calculateLogsBloom(ctx, rc))
515+
SetReceipts(ws.receipts).
516+
SetReceiptRoot(calculateReceiptRoot(ws.receipts)).
517+
SetLogsBloom(calculateLogsBloom(ctx, ws.receipts))
510518
return blkBuilder, nil
511519
}

0 commit comments

Comments
 (0)