-
Notifications
You must be signed in to change notification settings - Fork 588
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
refactor(indexer): Imorove error handling, add IndexerError, allow to ignore missing local delayed receipt (for mirroring, forknet) #11315
base: master
Are you sure you want to change the base?
Conversation
e07c06f
to
17bccc8
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #11315 +/- ##
==========================================
- Coverage 71.37% 71.33% -0.05%
==========================================
Files 790 790
Lines 160067 160161 +94
Branches 160067 160161 +94
==========================================
- Hits 114253 114246 -7
- Misses 40836 40938 +102
+ Partials 4978 4977 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
17bccc8
to
20088b9
Compare
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.
Nice, I think this will definitely be a good first step. It looks roughly okay to me, so I'll approve it for now, and tomorrow will actually check that it fixes the crash on a localnet (seems like it must though).
But I wonder if we can try and do something more direct with these delayed receipts. Because even with this fix, if we prepare genesis records from a time on mainnet when there were lots of delayed receipts, then the mirror traffic generator we will spend lots of CPU time in the indexer looking back 1000 blocks when it finds one of these genesis delayed receipts. I would guess this might actually add up to quite a lot.
Maybe it would be possible to have the indexer make an initial pass where when it runs for the first time it looks for all the delayed receipts (should just be in the state, like it's accessed here) , and then remembers all those receipt IDs, so that when we see one of them in the outcomes, we don't have to go back 1000 blocks to try and find it. Then for subsequent receipts, just remember all the receipts we see, and forget them when you see them in the outcomes for a block. The ones we still have stored are the ones that werent executed
Idk how hard that would be or whether it would be worth the time, but in the meantime I wonder if it's worth adding another config option to the indexer that says how far back to look? For the mirror process for example, I think we can live with just 5 or 10 or something, since it's not critical if we miss something
I second this. And since the in-memory cache for local delayed receipt is already implemented on the indexer side, it'd be great to reuse it by just providing all such receipts into that cache when starting from the genesis. Anyway, I see this feature irrelevant for the common indexer use case to be included as a built-in implementation. I'd rather consider implementing a way to start an indexer with some initial cache data. It would act like a tool for developers allowing to implement persistent cache and start the instance with initial data like in the case of mirror traffic generator. In the end I see it like a way to optionally pass the data to the cache, and then it's up to another tool to provide that data. What do you think @marcelo-gonzalez ? |
aa06ab0
to
f676cab
Compare
OK, so I have revisited this PR after some time. I've noticed I didn't get rid of one I got test data for Statelessnet where I caught this error with a not-found receipt and decided it was a great chance to make a proper handling of such cases. I am far from an expert in that are of @VanBarbascu @marcelo-gonzalez Can you please have a look? Maybe I used it in the wrong way. I am going to leave comments right in the code for you guys. Thanks! |
chain/chain/src/store/mod.rs
Outdated
@@ -1364,6 +1377,32 @@ impl ChainStoreAccess for ChainStore { | |||
.map_err(|e| e.into()) | |||
} | |||
|
|||
fn get_delayed_receipt(&self, receipt_id: &CryptoHash) -> Result<Option<Arc<Receipt>>, Error> { | |||
let delayed_receipts_indices: Option<TrieQueueIndices> = |
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 place returns None
when I test.
I wonder whether it is the wrong use of the store or whether the problem is that the Receipt
I am looking for is not just Delayed but Local Delayed. Do such receipts even end up in the Genesis records file during the state dump? 🤔
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.
cc @Longarithm for visibility. Where I need to be taught
… ignore missing local delayed receipt (for mirroring, forknet)
…net/mocknet), improve Indexer to try to find it through ViewClient before going 1000 blocks behind
…g ExecutionOutcome instead of entire block
283abc9
to
f873e5e
Compare
After some checks and experiments, I have reverted the attempt to look for DelayedReceipts in the database. The approach I was using was wrong and doing that correctly doesn't look better than what we currently have. So in the end, I've adjusted the logic around the flag Anyway, this flag is not recommended for production. Forknet, localnet, testnet only. |
Resolves #11313 (see
ignore_missing_local_delayed_receipt
in the Breaking Changes section)IndexerError
fromIndexer::start
method to allow better error handling in the client codetokio::sync::mpsc::channel
to allow more control over the indexer job with new methodIndexer::streamer_channel()
Indexer::start_streamer(sender: Sender<StreamerMessage>)
to allow more control over the indexer jobYou can use the new
Indexer::start_streamer
method to start the indexer job with a customtokio::sync::mpsc::channel
sender. This method is async and returns aResult<(), IndexerError>
.Breaking changes
ignore_missing_local_delayed_receipt
boolean flag to theIndexerConfig
struct to allow ignoring missing local delayed receipts. This flag should befalse
by default, so if you don't want to ignore missing local delayed receipts, you don't need to change anything. If you want to ignore missing local delayed receipts, you should set this flag totrue
in theIndexerConfig
struct.Even though this is a breaking change, the change to the existing code base should be minimal. You should just add the
ignore_missing_local_delayed_receipt
flag to theIndexerConfig
struct and set it tofalse
if you don't want to ignore missing local delayed receipts (the behaviour you have right now, it will panic if the local delayed receipt is missing) or set it totrue
if you want to ignore missing local delayed receipts. Warning! in this case the indexer will skip the entire block since it can't create a consistentStreamerMessage
without a local delayed receipt.