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

Headers-first synchronization and DoS protections #875

Closed
wants to merge 12 commits into from

Conversation

braydonf
Copy link
Contributor

This is an implementation of the solutions described in the paper Bitcoin Chain Width Expansion Denial-of-Service Attacks. For broad discussion regarding the paper and solutions please reply via the bitcoin-dev mailing list topic for the subject.

braydonf and others added 12 commits October 3, 2019 16:50
Headers:
  - Headers are added to the chain independently with the new
    method `addHeader()`, the headers should be added to the
    chain before blocks.
  - The width of the headers is limited to prevent a chain
    expansion attack. The chains with the least work are pruned
    and headers are now indexed by chainwork. This also brings the
    feature that alternative chains can be removed independently.
  - The new `isRecent()` method is used to determine if a the
    header chain is in recent time. It is similar to `isFull()`
    however works for the header chain.
  - The `mostWork()` method is used to get the most work header,
    this is often used for locating which blocks to download.
  - The new `detach()` method that is similar to `reset()`. However,
    it will only disconnect blocks from the chain and will keep the
    headers and alternative header chains. This method has an
    associated `attach()` method that can be used to connect a
    block entry that has already been added and saved but is
    not connected.
  - There are now methods `hasSeenHeader` and `hasHeader` to
    distinguish between the two different states.
  - Optimizations have been made for finding forks and getting
    ancestors that are not part of the main chain. This includes a
    new method called `commonAncestor` and replaces `findFork`. There
    is also additional indexing to be able to skip to ancestors for
    performance purposes.
  - SPV will now validate headers completely.

Blocks:
  - Blocks can now be added to the chain out-of-order via `add()`.
  - Blocks MUST NOT be added to the chain without sufficient
    chain work. The block should be part of a header chain with
    greater work than the current tip.
  - There are no more orphan or alternative blocks.
  - SPV merkle blocks are now stored on disk for a limited time.
    This provides the capability to store transactions that may
    not have been sent to the wallet yet or added to the main chain.

Chain:
  - The chain will now emit "bad block" when a a block is validated
    to be invalid. This event should be listened to as there may not
    be a validation error when the block is added via `add()` as it
    has not been connected to the chain.
  - The chain will always resolve to the most work valid chain, even
    in the event of validation error.
  - Blocks marked as invalid are now persisted to disk and will be
    pruned along with the headers.
- Update RPC methods.
- Connect preclose to chain during close.
- Add blockstore to SPV node.
- Detach the chain during wallet filter updates.
- Update node test.
- Download and add headers to chain before blocks.
- Download multiple blocks from multiple peers in parallel
  within a window.
- Do not download blocks unless part of header chain with greater
  work than the current best validated chain.

Co-authored-by: Braydon Fuller <courier@braydon.com>
- Limit the rate that unrequested headers can be received.
- Delay requesting headers based on header chainwork.
@braydonf
Copy link
Contributor Author

braydonf commented Oct 16, 2019

As mentioned on the mailing list: Limiting the width of the chain would not be effective unless the timewarp off-by-one bug is resolved — the height can be extended instead. Rate limiting based on chainwork will slow timewarped low work chains, however.

@braydonf
Copy link
Contributor Author

I'm closing for now, and will leave this branch as it is currently. A modified approach will be necessary considering timewarp attacks.

@braydonf braydonf closed this Oct 16, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants