-
Notifications
You must be signed in to change notification settings - Fork 328
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[factory] add parent to workingset #4539
base: master
Are you sure you want to change the base?
Conversation
@@ -356,7 +360,8 @@ func (sf *factory) Validate(ctx context.Context, blk *block.Block) error { | |||
if err := ws.ValidateBlock(ctx, blk); err != nil { | |||
return errors.Wrap(err, "failed to validate block with workingset in factory") | |||
} | |||
sf.putIntoWorkingSets(key, ws) | |||
sf.workingsets.Add(key, ws) | |||
sf.workingsets.Add(ws.height, ws) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is success validation for block n
, validation of the next block may continue which needs the state changes in this block, so adding ws
to cache, which will become parent of next block's workingset
@@ -398,7 +403,8 @@ func (sf *factory) NewBlockBuilder( | |||
|
|||
blkCtx := protocol.MustGetBlockCtx(ctx) | |||
key := generateWorkingSetCacheKey(blkBuilder.GetCurrentBlockHeader(), blkCtx.Producer.String()) | |||
sf.putIntoWorkingSets(key, ws) | |||
sf.workingsets.Add(key, ws) | |||
sf.workingsets.Add(ws.height, ws) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is used by new block proposal, so for the same reason adding ws
to cache
} | ||
ws.detachParent() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is used by CommitBlock()
, at this time parent of current ws
must have successfully committed his state changes into stateDB, so the current ws
must only rely on itself when processing the block
func (sf *factory) putIntoWorkingSets(key hash.Hash256, ws *workingSet) { | ||
sf.mutex.Lock() | ||
defer sf.mutex.Unlock() | ||
sf.workingsets.Add(key, ws) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sf.workingsets
is thread-safe cache, so no need to lock
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
quick clean-up not relevant to primary PR
break | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
both factory and statedb have the same workingset cache.LRUCache
, these can become a new small component WorkingSetCollection
later
} | ||
} | ||
if fCtx.CorrectTxLogIndex { | ||
updateReceiptIndex(receipts) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this func is not used any more
@@ -322,6 +318,9 @@ func (ws *workingSet) freshAccountConversion(ctx context.Context, actCtx *protoc | |||
|
|||
// Commit persists all changes in RunActions() into the DB | |||
func (ws *workingSet) Commit(ctx context.Context) error { | |||
if err := ws.verifyParent(); err != nil { | |||
return err | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if parent is abandoned, the workingset is not valid, abort here
@@ -508,6 +519,9 @@ func (ws *workingSet) Process(ctx context.Context, actions []*action.SealedEnvel | |||
} | |||
|
|||
func (ws *workingSet) processWithCorrectOrder(ctx context.Context, actions []*action.SealedEnvelope) error { | |||
if err := ws.verifyParent(); err != nil { | |||
return err | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if parent is abandoned, the workingset is not valid, abort here
@@ -346,6 +345,11 @@ func (ws *workingSet) State(s interface{}, opts ...protocol.StateOption) (uint64 | |||
if cfg.Keys != nil { | |||
return 0, errors.Wrap(ErrNotSupported, "Read state with keys option has not been implemented yet") | |||
} | |||
if ws.parent != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should first query from the current ws, and if not found, then query from the parent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point, but this is a little complicated, for example, assume
- in the DB,
state(k) = 100
- in the parent workingset
state(k) = 98
(there's a transfer of 2 token in pending block)
in this case, we should honor the value in parent workingset
assume there's another transfer of 3 token in current block, then state(k) = 95
now, and things get even more complicated: for next read, should honor the value in current workingset
i think the return value of State/Read
should indicate if the value is from workingset cache, and honor the value in cache over that from DB
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe we can replace db store with parent
state/factory/workingset.go
Outdated
@@ -361,6 +365,13 @@ func (ws *workingSet) States(opts ...protocol.StateOption) (uint64, state.Iterat | |||
if cfg.Key != nil { | |||
return 0, nil, errors.Wrap(ErrNotSupported, "Read states with key option has not been implemented yet") | |||
} | |||
if ws.parent != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
if height > 0 { | ||
parent = getWorkingSetByHeight(sdb.workingsets, height-1) | ||
} | ||
return newWorkingSet(height, store, parent), nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it only necessary to set the parent when height-1 is not yet confirmed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and should NOT newWorkingSet at hanging height, that is height-1 is either already confirmed, or there is already an existing working set.
} | ||
if err = ws.verifyParent(); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only valid when parent already confirmed
Quality Gate passedIssues Measures |
Description
Prep for pipelined
ValidateBlock/CommitBlock
.Fixes #(issue)
Type of change
Please delete options that are not relevant.
How Has This Been Tested?
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
Test Configuration:
Checklist: