Skip to content
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

fix: seed forking handler with unconfirmed blocks to improve startup stability #505

Merged
merged 9 commits into from
Mar 14, 2024

Conversation

MicaiahReid
Copy link
Contributor

@MicaiahReid MicaiahReid commented Feb 15, 2024

Description

If Chainhook restarts in the middle of a reorg taking place, it doesn't have any context for choosing the canonical fork. Then when block collisions take place, Chainhook fails to process the new blocks, causing gaps in the blocks Chainhook has available for evaluation.

This PR seeds the stacks block indexer with unconfirmed blocks on startup, so that Chainhook has the necessary context to handle a reorg.

Most of the PR is to add two tests:

  • I've added some new functionality to our very thorough indexer tests
    • In addition to providing the blocks to be mined and the order to mine them, we also now allow providing some "unconfirmed" blocks to seed the block pool with.
    • I've added some test cases that reproduce what caused outages on the Platform's Chainhook node
  • I've added a new service test that:
    • Verifies that unconfirmed blocks are stored on restart
    • Verifies that those blocks are used to seed the block pool, and that a reorg is handled correctly.

I committed these tests before adding the fix, so you can confirm the fix by checking out the commits with the new tests (96d8249 and 9aad55e), seeing that the tests break, then pulling the last commit to see that the fix works.

Fixes #487

@MicaiahReid MicaiahReid changed the title fix: seed forking handler with unconfirmed blocks to improve startup stability [wip] fix: seed forking handler with unconfirmed blocks to improve startup stability Feb 15, 2024
@MicaiahReid MicaiahReid temporarily deployed to Development-mainnet February 15, 2024 22:00 — with GitHub Actions Inactive
@MicaiahReid MicaiahReid force-pushed the fix-reorg-handler branch 2 times, most recently from 4a1a635 to e7b7573 Compare February 20, 2024 21:23
@MicaiahReid MicaiahReid requested a review from lgalabru February 20, 2024 21:35
@MicaiahReid MicaiahReid changed the title [wip] fix: seed forking handler with unconfirmed blocks to improve startup stability fix: seed forking handler with unconfirmed blocks to improve startup stability Feb 20, 2024
@@ -38,6 +39,7 @@ impl Service {
pub async fn run(
&mut self,
predicates_from_startup: Vec<ChainhookFullSpecification>,
observer_commands_tx_rx: Option<(Sender<ObserverCommand>, Receiver<ObserverCommand>)>,
Copy link
Contributor Author

@MicaiahReid MicaiahReid Feb 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Being able to create the observer commands tx externally allows stopping the service from a test.

I don't usually love changing non-test code for tests, but I was stuck on this one.

@@ -1,33 +1,37 @@
use crate::config::Config;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is mostly just moving some test setup functions here from a different file, and adding the TestSetupResult struct to clean up the response a bit.

@@ -8,7 +8,7 @@ use chainhook_sdk::types::{
STXTransferEventData, SmartContractEventData, StacksTransactionEventPayload,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file's changes are to allow adding a fork_id and parent_fork_id to the stacks blocks that are mined for tests.

ChainhookFullSpecification, ChainhookSpecification, StacksChainhookFullSpecification,
};
use chainhook_sdk::types::{Chain, StacksNetwork};
use chainhook_sdk::chainhooks::types::ChainhookFullSpecification;
Copy link
Contributor Author

@MicaiahReid MicaiahReid Feb 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of the changes in this file are more cleanup:

  • moving out helpers
  • our mine_block function now takes fork ids, so updating existing calls to that function to pass an fork id
  • our helpers have a new struct for the return value, so updating the tests that use that helper
  • simplifying our code to clean up temp test data

The actual change is the addition of the it_seeds_block_pool_on_startup test all the way at the bottom

@@ -15,262 +15,271 @@ use test_case::test_case;

#[test]
fn test_stacks_vector_001() {
process_stacks_blocks_and_check_expectations(helpers::stacks_shapes::get_vector_001());
process_stacks_blocks_and_check_expectations((helpers::stacks_shapes::get_vector_001(), None));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it's not ideal that we have this additional argument being passed. The other option is to duplicate the process_stacks_blocks_and_check_expectations function with the changes I made to seed the block pool, so only the two new tests need to call it. Pick your poison ¯_(ツ)_/¯


/// Vector 053: Generate the following blocks
///
/// A1(0) - B1(1) - C1(3)
Copy link
Contributor Author

@MicaiahReid MicaiahReid Feb 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A1(0)

I've added the (0) to mean that this data already existed on startup (so we're seeding the block pool with this block)

Copy link
Contributor

@lgalabru lgalabru left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@MicaiahReid MicaiahReid merged commit b77aca2 into develop Mar 14, 2024
3 checks passed
@MicaiahReid MicaiahReid deleted the fix-reorg-handler branch March 14, 2024 20:42
MicaiahReid added a commit that referenced this pull request Mar 27, 2024
…stability (#505)

### Description

If Chainhook restarts in the middle of a reorg taking place, it doesn't
have any context for choosing the canonical fork. Then when block
collisions take place, Chainhook fails to process the new blocks,
causing gaps in the blocks Chainhook has available for evaluation.

This PR seeds the stacks block indexer with unconfirmed blocks on
startup, so that Chainhook has the necessary context to handle a reorg.

Most of the PR is to add two tests:
 - I've added some new functionality to our very thorough indexer tests
- In addition to providing the blocks to be mined and the order to mine
them, we also now allow providing some "unconfirmed" blocks to seed the
block pool with.
- I've added some test cases that reproduce what caused outages on the
Platform's Chainhook node
 - I've added a new service test that:
   - Verifies that unconfirmed blocks are stored on restart
- Verifies that those blocks are used to seed the block pool, and that a
reorg is handled correctly.

I committed these tests _before_ adding the fix, so you can confirm the
fix by checking out the commits with the new tests
(96d8249 and
9aad55e), seeing that the tests break,
then pulling the last commit to see that the fix works.

Fixes #487
MicaiahReid added a commit that referenced this pull request Mar 27, 2024
…stability (#505)

### Description

If Chainhook restarts in the middle of a reorg taking place, it doesn't
have any context for choosing the canonical fork. Then when block
collisions take place, Chainhook fails to process the new blocks,
causing gaps in the blocks Chainhook has available for evaluation.

This PR seeds the stacks block indexer with unconfirmed blocks on
startup, so that Chainhook has the necessary context to handle a reorg.

Most of the PR is to add two tests:
 - I've added some new functionality to our very thorough indexer tests
- In addition to providing the blocks to be mined and the order to mine
them, we also now allow providing some "unconfirmed" blocks to seed the
block pool with.
- I've added some test cases that reproduce what caused outages on the
Platform's Chainhook node
 - I've added a new service test that:
   - Verifies that unconfirmed blocks are stored on restart
- Verifies that those blocks are used to seed the block pool, and that a
reorg is handled correctly.

I committed these tests _before_ adding the fix, so you can confirm the
fix by checking out the commits with the new tests
(96d8249 and
9aad55e), seeing that the tests break,
then pulling the last commit to see that the fix works.

Fixes #487
github-actions bot pushed a commit that referenced this pull request Mar 27, 2024
## [1.4.0](v1.3.1...v1.4.0) (2024-03-27)

### Features

* detect http / rpc errors as early as possible ([ad78669](ad78669))
* use stacks.rocksdb for predicate scan ([#514](#514)) ([a4f1663](a4f1663)), closes [#513](#513) [#485](#485)

### Bug Fixes

* enable debug logs in release mode ([#537](#537)) ([fb49e28](fb49e28))
* improve error handling, and more! ([#524](#524)) ([86b5c78](86b5c78)), closes [#498](#498) [#521](#521) [#404](#404) [/github.com//issues/517#issuecomment-1992135101](https://github.com/hirosystems//github.com/hirosystems/chainhook/issues/517/issues/issuecomment-1992135101) [#517](#517) [#506](#506) [#510](#510) [#519](#519)
* log errors on block download failure; implement max retries ([#503](#503)) ([0fc38cb](0fc38cb))
* **metrics:** update latest ingested block on reorg ([#515](#515)) ([8f728f7](8f728f7))
* order and filter blocks used to seed forking block pool ([#534](#534)) ([a11bc1c](a11bc1c))
* seed forking handler with unconfirmed blocks to improve startup stability ([#505](#505)) ([485394e](485394e)), closes [#487](#487)
* skip db consolidation if no new dataset was downloaded ([#513](#513)) ([983a165](983a165))
* update scan status for non-triggering predicates ([#511](#511)) ([9073f42](9073f42)), closes [#498](#498)
github-actions bot pushed a commit that referenced this pull request Apr 6, 2024
## [1.5.0](v1.4.1...v1.5.0) (2024-04-06)

### Features

* add brc-20 schemas for ordhook ([#551](#551)) ([1e25a8f](1e25a8f))
* detect http / rpc errors as early as possible ([e515116](e515116))
* rm blocks ([f35498d](f35498d))
* use stacks.rocksdb for predicate scan ([#514](#514)) ([0baae10](0baae10)), closes [#513](#513) [#485](#485)

### Bug Fixes

* build error ([03b3938](03b3938))
* log errors on block download failure; implement max retries ([#503](#503)) ([3bfb0e1](3bfb0e1))
* **metrics:** update latest ingested block on reorg ([#515](#515)) ([823713a](823713a))
* order and filter blocks used to seed forking block pool ([#534](#534)) ([a2865b7](a2865b7))
* revisit 7+ blocks reorg handling ([#553](#553)) ([184fd07](184fd07))
* seed forking handler with unconfirmed blocks to improve startup stability ([#505](#505)) ([b77aca2](b77aca2)), closes [#487](#487)
* skip db consolidation if no new dataset was downloaded ([#513](#513)) ([b1469a6](b1469a6))
* update scan status for non-triggering predicates ([#511](#511)) ([32cdfee](32cdfee)), closes [#498](#498)
Copy link

github-actions bot commented Apr 6, 2024

🎉 This PR is included in version 1.5.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

vabanaerytk added a commit to vabanaerytk/chainhook that referenced this pull request Aug 7, 2024
## [1.4.0](hirosystems/chainhook@v1.3.1...v1.4.0) (2024-03-27)

### Features

* detect http / rpc errors as early as possible ([4a3e7e8](hirosystems/chainhook@4a3e7e8))
* use stacks.rocksdb for predicate scan ([#514](hirosystems/chainhook#514)) ([bff1372](hirosystems/chainhook@bff1372)), closes [#513](hirosystems/chainhook#513) [#485](hirosystems/chainhook#485)

### Bug Fixes

* enable debug logs in release mode ([#537](hirosystems/chainhook#537)) ([5ff21e0](hirosystems/chainhook@5ff21e0))
* improve error handling, and more! ([#524](hirosystems/chainhook#524)) ([2cfedd7](hirosystems/chainhook@2cfedd7)), closes [#498](hirosystems/chainhook#498) [#521](hirosystems/chainhook#521) [#404](hirosystems/chainhook#404) [/github.com/hirosystems/chainhook/issues/517#issuecomment-1992135101](https://github.com/hirosystems//github.com/hirosystems/chainhook/issues/517/issues/issuecomment-1992135101) [#517](hirosystems/chainhook#517) [#506](hirosystems/chainhook#506) [#510](hirosystems/chainhook#510) [#519](hirosystems/chainhook#519)
* log errors on block download failure; implement max retries ([#503](hirosystems/chainhook#503)) ([0454a4f](hirosystems/chainhook@0454a4f))
* **metrics:** update latest ingested block on reorg ([#515](hirosystems/chainhook#515)) ([7653766](hirosystems/chainhook@7653766))
* order and filter blocks used to seed forking block pool ([#534](hirosystems/chainhook#534)) ([ff775de](hirosystems/chainhook@ff775de))
* seed forking handler with unconfirmed blocks to improve startup stability ([#505](hirosystems/chainhook#505)) ([063e0e2](hirosystems/chainhook@063e0e2)), closes [#487](hirosystems/chainhook#487)
* skip db consolidation if no new dataset was downloaded ([#513](hirosystems/chainhook#513)) ([f34dee3](hirosystems/chainhook@f34dee3))
* update scan status for non-triggering predicates ([#511](hirosystems/chainhook#511)) ([9647e72](hirosystems/chainhook@9647e72)), closes [#498](hirosystems/chainhook#498)
vabanaerytk added a commit to vabanaerytk/chainhook that referenced this pull request Aug 7, 2024
## [1.5.0](hirosystems/chainhook@v1.4.1...v1.5.0) (2024-04-06)

### Features

* add brc-20 schemas for ordhook ([#551](hirosystems/chainhook#551)) ([4cfa300](hirosystems/chainhook@4cfa300))
* detect http / rpc errors as early as possible ([4ef6650](hirosystems/chainhook@4ef6650))
* rm blocks ([3d57290](hirosystems/chainhook@3d57290))
* use stacks.rocksdb for predicate scan ([#514](hirosystems/chainhook#514)) ([e8bc60b](hirosystems/chainhook@e8bc60b)), closes [#513](hirosystems/chainhook#513) [#485](hirosystems/chainhook#485)

### Bug Fixes

* build error ([f0fb623](hirosystems/chainhook@f0fb623))
* log errors on block download failure; implement max retries ([#503](hirosystems/chainhook#503)) ([7bd6efd](hirosystems/chainhook@7bd6efd))
* **metrics:** update latest ingested block on reorg ([#515](hirosystems/chainhook#515)) ([5a7d64e](hirosystems/chainhook@5a7d64e))
* order and filter blocks used to seed forking block pool ([#534](hirosystems/chainhook#534)) ([bb2a545](hirosystems/chainhook@bb2a545))
* revisit 7+ blocks reorg handling ([#553](hirosystems/chainhook#553)) ([3632176](hirosystems/chainhook@3632176))
* seed forking handler with unconfirmed blocks to improve startup stability ([#505](hirosystems/chainhook#505)) ([a84fc4c](hirosystems/chainhook@a84fc4c)), closes [#487](hirosystems/chainhook#487)
* skip db consolidation if no new dataset was downloaded ([#513](hirosystems/chainhook#513)) ([440a8e3](hirosystems/chainhook@440a8e3))
* update scan status for non-triggering predicates ([#511](hirosystems/chainhook#511)) ([115ac28](hirosystems/chainhook@115ac28)), closes [#498](hirosystems/chainhook#498)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

store blocks from non-canonical forks; supply them to indexer on startup
2 participants