-
Notifications
You must be signed in to change notification settings - Fork 199
[Storage] Refactor indexing transaction error message #8021
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
Changes from all commits
af1c3e6
d86569f
af54bfe
b413203
a1a371d
157d4ec
43ef330
155220d
e666a2a
5277616
28b4f19
bbd6ed9
af6427a
4eb3b45
45524d0
1ee701b
79751ac
e2039ac
c9563fd
6dddf0a
346cdae
f07a652
e8036e7
190c46d
9bcdb06
147f3cc
9c36182
3fc2a9a
eefd772
dd6cfa2
780e20a
4e11ecf
cafb925
ac316dd
64dfc09
4ac5c28
ac296c1
9d0cbdb
51a1895
c20915b
9a21aea
127db87
015edcc
73c6514
9d9a747
6f77ad3
4854931
a19f958
348284d
7636d0b
e645c88
fa97bbb
94a08b5
ee7a627
c51b871
b7918aa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -1,6 +1,7 @@ | ||||||||
| package stores | ||||||||
|
|
||||||||
| import ( | ||||||||
| "errors" | ||||||||
| "fmt" | ||||||||
|
|
||||||||
| "github.com/jordanschalm/lockctx" | ||||||||
|
|
@@ -34,8 +35,16 @@ func NewEventsStore( | |||||||
| // | ||||||||
| // No error returns are expected during normal operations | ||||||||
| func (e *EventsStore) Persist(_ lockctx.Proof, batch storage.ReaderBatchWriter) error { | ||||||||
| if err := e.persistedEvents.BatchStore(e.blockID, []flow.EventsList{e.data}, batch); err != nil { | ||||||||
| err := e.persistedEvents.BatchStore(e.blockID, []flow.EventsList{e.data}, batch) | ||||||||
| if err != nil { | ||||||||
| if errors.Is(err, storage.ErrAlreadyExists) { | ||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❓Question I assume this is anticipating future changes? If I am not mistaken, at the moment, In addition, the storage API is lacking error documentation, so added the following todo: Lines 29 to 31 in 9a21aea
Overall, I think we need to come back to the events and add overwrite protection checks. After adding these checks, the code in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, the refactor of the implementation has been addressed in this PR: So the error handling is added here first. |
||||||||
| // CAUTION: here we assume that if something is already stored for our blockID, then the data is identical. | ||||||||
| // This only holds true for sealed execution results, whose consistency has previously been verified by | ||||||||
| // comparing the data's hash to commitments in the execution result. | ||||||||
| return nil | ||||||||
| } | ||||||||
| return fmt.Errorf("could not add events to batch: %w", err) | ||||||||
| } | ||||||||
|
|
||||||||
| return 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.
I don't like this usage here, that the block persister has to know what locks needs to be acquired. The block persister is supposed to be ignorant about what db operation the underlying individual persisters running, therefore doesn't know about the locks to acquire, it supposed to only create a batch object, and ensure it's committed.
Maybe we can revisit this, when working on #7910. My idea is that we could let the BatchStore functor to return a required lock ID and the functor, so that the locker doesn't need to remember what lock to acquire.
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.
I agree it's slightly awkward, but I think returning the expected lock alongside the functor could cause other problems:
persisterStoresto make sure the locks are acquired in the right orderFundamentally, the layer at which locks are acquired does need to know something about what locks are being acquired. I think just having the upper layer explicitly acquire the needed locks is the simplest way to deal with this pattern.
Uh oh!
There was an error while loading. Please reload this page.
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.
my 10 cents on this conversation:
On the one hand, acquiring the locks one by one looks verbose. But I don't think this is a problem of the lock proof pattern. Here are my reasonings:
The current
BlockPersisterimplementation already very precisely documents that is is for persisting an execution resultflow-go/module/executiondatasync/optimistic_sync/persisters/block.go
Line 16 in dd6cfa2
BlockPersisteralso has to know which locks to acquire (all that requires for persisting a result)With moving to pebble, the lower-level storage layer has not longer the ability to self-sufficiently protect against illegal data changes. Now, the business logic has be be involved by acquiring and holding locks.
Components that require different locks simply don't satisfy the same API anymore. Higher-level business logic has to be aware which locks to acquire, that's simply a consequence of the storage layer no longer having snapshot isolation for read + writes.
From my perspective, you can try to hide the reality that the type of lock that must be held is conceptually part of the interface (even through the compiler only enforces that some lock proof is given, but is oblivious about the lock). I think thereby you inadvertently create problems in other parts that then no longer have the information they need: