Commit Graph

266 Commits

Author SHA1 Message Date
teor 0bac2dafcc Split out a separate `median_time_past` function 2020-12-04 10:44:36 +10:00
teor ab486d336f Update the contextual difficulty module doc 2020-12-04 10:44:36 +10:00
teor 44f2326672 Move the RocksDB column family list into finalized_state
The list was previously split between config and finalized_state.
2020-12-02 15:32:36 +10:00
Henry de Valence 7c08c0c315 consensus: check Merkle roots
As a side effect of computing Merkle roots, we build a list of
transaction hashes.  Instead of discarding these, add them to
PreparedBlock and FinalizedBlock so that they can be reused rather than
recomputed.

This commit adds Merkle root validation to:

1. the block verifier;
2. the checkpoint verifier.

In the first case, Bitcoin Merkle tree malleability has no effect,
because only a single Merkle tree in each malleablity set is valid (the
others have duplicate transactions).

In the second case, we need to check that the Merkle tree does not contain any
duplicate transactions.

Closes #1385
Closes #906
2020-12-01 10:14:44 +10:00
Alfredo Garcia 4544463059
Inbound `FindBlocks` and `FindHeaders` (#1347)
* implement inbound `FindBlocks`
* Handle inbound peer FindHeaders requests
* handle request before having any chain tip
* Split `find_chain_hashes` into smaller functions

Add a `max_len` argument to support `FindHeaders` requests.

Rewrite the hash collection code to use heights, so we can handle the
`stop` hash and "no intersection" cases correctly.

* Split state height functions into "any chain" and "best chain"
* Rename the best chain block method to `best_block`
* Move fmt utilities to zebra_chain::fmt
* Summarise Debug for some Message variants

Co-authored-by: teor <teor@riseup.net>
Co-authored-by: Jane Lusby <jlusby42@gmail.com>
2020-12-01 07:30:37 +10:00
teor d007c76488 Turn a chain length check into an assert 2020-12-01 07:27:30 +10:00
teor d1ba1146d4 Add intra-doc links 2020-12-01 07:27:30 +10:00
teor 1e4ce74c93 Turn the relevant chain into a Vec before using it
Some checks use the same blocks, so we take a copy of the block borrows
before using them. That way, we don't have to manage the position of the
iterator between checks.
2020-12-01 07:27:30 +10:00
teor 712dd9ddf3 Make a module `pub(crate)` rather than `pub` 2020-12-01 07:27:30 +10:00
teor ec6ef93b7b Simplify an ExpandedDifficulty division 2020-12-01 07:27:30 +10:00
teor d64c2976e3 Rewrite iterator processing using unzip
Co-authored-by: Jane Lusby <jlusby42@gmail.com>
2020-12-01 07:27:30 +10:00
teor 91476535d3 Doc comment formatting
Co-authored-by: Jane Lusby <jlusby42@gmail.com>
2020-12-01 07:27:30 +10:00
teor 678e6ad090 Implement difficulty_threshold_is_valid 2020-12-01 07:27:30 +10:00
teor 750f096a99 Implement testnet minimum difficulty 2020-12-01 07:27:30 +10:00
teor bb9c4918bf Implement threshold_bits 2020-12-01 07:27:30 +10:00
teor f0a49d64bf Split out a median_timespan function 2020-12-01 07:27:30 +10:00
teor 054d6f0525 Implement median_timespan_bounded 2020-12-01 07:27:30 +10:00
teor 75519b0ae9 Implement averaging_window_timespan 2020-12-01 07:27:30 +10:00
teor bcabf75fe9 Replace integer lengths with named constants 2020-12-01 07:27:30 +10:00
teor e07b0bc8da Implement median_time
And enough stubs to run it on real data.
2020-12-01 07:27:30 +10:00
teor 741c44cd55 Implement mean_target_difficulty
And enough stub code to actually run it on the context.
2020-12-01 07:27:30 +10:00
teor 939c2b97a6 Implement AdjustedDifficulty creation
Also:
* call the difficulty check from `block_is_contextually_valid`
* add a stub `difficulty_threshold_is_valid` function
2020-12-01 07:27:30 +10:00
teor fa03b83351 Update some contextual validation comments and error messages 2020-12-01 07:27:30 +10:00
teor 176923a771
Add an info-level log when UTXO requests are pruned (#1396)
And a debug-level log when no requests are pruned.

I'm seeing some hangs during the initial sync, these logs might help
identify the cause.
2020-11-26 17:26:10 +10:00
teor 31eb0a5126 Avoid verbose default logs
Temporary fix so that Zebra's default logs support a typical workflow:
1. Developer or user runs Zebra with the default config
2. They send the logs to a terminal
3. When they see a bug, they copy-paste the last few log lines into a
   bug report

This is the same change that was merged in #1373 and reverted in #1375.
We'll create a consistent logging design for Zebra in ticket #1381.
2020-11-25 10:55:15 -08:00
teor b1bbb13978
Make debug_stop_at_height and ephemeral work together (#1339)
* Make debug_stop_at_height and ephemeral work together

* if `debug_stop_at_height` and `ephemeral` are set, delete the database
  files after reaching the stop height
* drop or flush the database before `debug_stop_at_height` exits Zebra
2020-11-25 15:04:18 +10:00
Deirdre Connolly 2a21c86b91 I before E except after C (or uh, not-english) 2020-11-24 22:23:57 -05:00
Henry de Valence 2e0ed94b22 Revert "Downgrade a per-block log to debug level"
This reverts commit 15d26e3c47.
2020-11-24 14:39:45 -05:00
teor 15d26e3c47 Downgrade a per-block log to debug level 2020-11-24 10:56:57 -05:00
Henry de Valence 040e50b183 state: service::utxo -> service::pending_utxos 2020-11-23 22:18:43 -08:00
Henry de Valence 342eb166ff state: track UTXO provenance
This commit changes the state system and database format to track the
provenance of UTXOs, in addition to the outputs themselves.
Specifically, it tracks the following additional metadata:

- the height at which the UTXO was created;
- whether or not the UTXO was created from a coinbase transaction or
  not.

This metadata will allow us to:

- check the coinbase maturity consensus rule;
- check the coinbase inputs => no transparent outputs rule;
- implement lookup of transactions by utxo (using the height to find the
  block and then scanning the block) for a future RPC mechanism.

Closes #1342
2020-11-23 22:18:43 -08:00
teor 00c52d28cd Appease rustfmt 2020-11-23 14:16:39 +10:00
teor acf6096103 Appease clippy stable 2020-11-23 14:16:39 +10:00
Henry de Valence 2a4a89c002 state,zebrad: tidy span levels for good INFO output
This provides useful and not too noisy output at INFO level.  We do an
info-level message on every block commit instead of trying to do one
message every N blocks, because this is useful both for initial block
sync as well as continuous state updates on new blocks.
2020-11-23 14:16:39 +10:00
Henry de Valence e0817d1747 state: introduce PreparedBlock, FinalizedBlock
This change introduces two new types:

- `PreparedBlock`, representing a block which has undergone semantic
  validation and has been prepared for contextual validation;
- `FinalizedBlock`, representing a block which is ready to be finalized
  immediately;

and changes the `Request::CommitBlock`,`Request::CommitFinalizedBlock`
variants to use these types instead of their previous fields.

This change solves the problem of passing data between semantic
validation and contextual validation, and cleans up the state code by
allowing it to pass around a bundle of data.  Previously, the state code
just passed around an `Arc<Block>`, which forced it to needlessly
recompute block hashes and other data, and was incompatible with the
already-known but not-yet-implemented data transfer requirements, namely
passing in the Sprout and Sapling anchors computed during contextual
validation.

This commit propagates the `PreparedBlock` and `FinalizedBlock` types
through the state code but only uses their data opportunistically, e.g.,
changing .hash() computations to use the precomputed hash.  In the
future, these structures can be extended to pass data through the
verification pipeline for reuse as appropriate.  For instance, these
changes allow the sprout and sapling anchors to be propagated through
the state.
2020-11-23 14:16:39 +10:00
Henry de Valence 3f78476693 state: check queued blocks for known UTXOs
The behavior of a request for a UTXO from a previous block depends on
whether that block has already been submitted to the state, or not:

* if it has, the state should be able to find it and answer immediately.
* if it has not, the state should see it in a later request.

However, the previous code only checked committed blocks, not queued
blocks, so if the block containing the UTXO had already arrived but had
not been committed, it would never be scanned.

This patch fixes the problem but is a bad solution, duplicating
computation between the block verifier and the state.  A better fix
follows in the next commit.
2020-11-23 14:16:39 +10:00
Henry de Valence 719a48ad9e state: shorten tracing messages
Make tracing messages more concise by omitting information already
contained in a parent span and by shortening messages.  This makes them
easier to read.
2020-11-23 14:16:39 +10:00
Henry de Valence f0810b028d state,consensus,sync: shorten span lengths
These changes help reduce the size of the resulting spans, making the
output more compact.  Together they save about 30-40 characters.
2020-11-23 14:16:39 +10:00
Henry de Valence 77b60f3a30 state: add traces for utxo scanning 2020-11-23 14:16:39 +10:00
Jane Lusby 4c9bb87df2
zebra-state: replace sled with rocksdb (#1325)
## Motivation

Prior to this PR we've been using `sled` as our database for storing persistent chain data on the disk between boots. We picked sled over rocksdb to minimize our c++ dependencies despite it being a less mature codebase. The theory was if it worked well enough we'd prefer to have a pure rust codebase, but if we ever ran into problems we knew we could easily swap it out with rocksdb.

Well, we ran into problems. Sled's memory usage was particularly high, and it seemed to be leaking memory. On top of all that, the performance for writes was pretty poor, causing us to become bottle-necked on sled instead of the network.

## Solution

This PR replaces `sled` with `rocksdb`. We've seen a 10x improvement in memory usage out of the box, no more leaking, and much better write performance. With this change writing chain data to disk is no longer a limiting factor in how quickly we can sync the chain.

The code in this pull request has:
  - [x] Documentation Comments
  - [x] Unit Tests and Property Tests

## Review

@hdevalence
2020-11-18 18:05:06 -08:00
Jane Lusby 5a6a9fd51e remove some references to sled in serialization definition module 2020-11-18 15:09:43 -05:00
Jane Lusby a122a547be reorganize modules for consistency 2020-11-18 15:09:43 -05:00
teor 2f53ff44f7 Move chain order assertions to commit_finalized_direct
And remove a duplicate assert in the contextual verification function.
2020-11-17 13:16:31 +10:00
teor d7d15984eb Move all contextual validation code into its own function
This change has two benefits:
* reduces conflicts with the sled refactor and any replacement
* allows the function to be called independently for testing
2020-11-17 11:46:57 +10:00
Jane Lusby 4c2b44be93
Add tests for QueuedBlocks (#1268)
* Add unit test for QueuedBlocks
* Add test for pruned blocks
2020-11-17 09:31:22 +10:00
Jane Lusby 57637560b9
Add internal iterator API for accessing relevant chain blocks (#1271)
* Add internal iterator API for accessing relevant chain blocks
* get blocks from all chains in non_finalized state
* Impl FusedIterator for service::Iter
* impl ExactSizedIterator for service::Iter
* let size_hint find heights in side chains

Co-authored-by: teor <teor@riseup.net>
2020-11-16 12:22:53 +10:00
Jane Lusby 7403897fda
Add transcript tests as described in the state service tracking issue (#1281)
* Add transcript test for requests while state is empty

* Add happy path test for each query once the state is populated

* let populate logic handle out of order blocks
2020-11-13 10:19:47 -08:00
Jane Lusby 8ba9d0114b
Add consensus critical check for sequential heights (#1291)
* Add consensus critical check for sequential heights
* document the check module
* Add unit tests for consensus checks
2020-11-13 14:26:16 +10:00
Jane Lusby beede1c03d tweek chain test to use set_work 2020-11-12 09:14:52 -05:00
Jane Lusby c41a7303fa Add helpers for setting work on fake chains 2020-11-12 09:14:52 -05:00
Jane Lusby dc9081b738 clarify test name 2020-11-12 09:14:52 -05:00
Jane Lusby a398e96f79 Update zebra-state/src/service/memory_state/non_finalized_state.rs
Co-authored-by: teor <teor@riseup.net>
2020-11-12 09:14:52 -05:00
Jane Lusby c54b07eb32 Update zebra-state/src/service/memory_state/non_finalized_state.rs
Co-authored-by: teor <teor@riseup.net>
2020-11-12 09:14:52 -05:00
Jane Lusby 8279c65218 Update zebra-state/src/service/memory_state/non_finalized_state.rs
Co-authored-by: teor <teor@riseup.net>
2020-11-12 09:14:52 -05:00
Jane Lusby dcc19f6b25 fully cover commit_block 2020-11-12 09:14:52 -05:00
Jane Lusby 74af22e5ca Add unit tests for 2020-11-12 09:14:52 -05:00
teor 41788c3f27
Add metrics for the non-finalized state and queue (#1263) 2020-11-10 11:11:58 +10:00
Jane Lusby 34f50d7ebb
Fix inconsistencies related to best chain order in RFC and state impl (#1267)
Prior to this PR we realized that the RFC had been drafted with the assumption that chains would be ordered from best to worst in `NonFinalizedState`. This assumption was incorrect, since `BTreeSet` only ever orders values in ascending order. This discrepancy was noticed and fixed in the code, but there were still some inconsistencies that needed to be cleaned up.

This PR updates all the incorrect or confusing comments about chain ordering in the RFC and code.
2020-11-09 15:53:16 -08:00
Jane Lusby 818fede30f
Reorganize memory_state to avoid giant test module (#1258)
Prior to this PR `memory_state` defined and implemented functionality for three different types, `Chain`, `NonFinalizedState`, and `QueuedBlocks`. Each of these components will need a fair number of unit tests, and I realized that as its currently organized it would be difficult to organize the tests or at a glance figure out which tests are testing which components.

This PR changes the organization of `memory_state` such that each component it exports is defined in its own module. In follow up PRs each module will get its own test module, which will focus exclusively on unit tests for the item defined there-in.

- [Tracking Issue](https://github.com/ZcashFoundation/zebra/issues/1250)
2020-11-09 10:05:18 -08:00
Jane Lusby e8a3a28869
swap best_chain_len and related constants to u32 for consistency (#1257) 2020-11-06 14:00:10 +10:00
Jane Lusby 714def990e
make state service use both finalized and non-finalized state (#1239)
* make service use both finalized and non-finalized state

* Document new functions

* add documentation to sled fns

* cleanup tip fn now that errors are gone

* rename height unwrap fn
2020-11-01 10:49:34 -08:00
teor 0d47b80e68
Fix a comment typo 2020-10-27 19:31:45 +10:00
Jane Lusby 971765ab30
Handle duplicate blocks in zebra-state (#1198)
## Motivation

The zebra-state service needs to be able to handle duplicate blocks.

## Solution

This implements changes already outlined by [The State
RFC](https://zebra.zfnd.org/dev/rfcs/0005-state-updates.html). We check for
successfully committed blocks first, since interacting with the queued blocks
struct at this point just complicates the implimentation. If the block has not
already been committed we then check if the block has already been queued, if
not we handle the block normally (normally here being the bit we already had
implemented).

## Documentation Changes

- [x] Update the state RFC to match the ways this fix departs from the design
	- the main thing is that I switched the order of checking for duplicates
- [x] ~~Add newly added functions to the state rfc~~ Decided not to do this because they're minor getters that don't influence the rest of the design and aren't exposed as part of the API
- [x] Document newly added functions inline

## Testing

## Related Issues

- fixes https://github.com/ZcashFoundation/zebra/issues/1182
- tracking issue https://github.com/ZcashFoundation/zebra/issues/1049

Co-authored-by: teor <teor@riseup.net>
2020-10-26 13:54:19 -07:00
Jane Lusby e05103323e
Implement Async Script Verification RFC (#961)
This commit begins the process of integrating `zcash_script` with the rest of the system for verifying scripts while syncing the block chain. It does so by adding the necessary support for looking up UTXOs from the state service and implements the first parts of the `script::Verifier` for looking up the necessary UTXOs in the state and then generating the necessary call to `zcash_script` to verify the script itself.

Co-authored-by: teor <teor@riseup.net>
2020-10-14 14:06:32 -07:00
Jane Lusby eaf5473efc
Add verification and state tracing events and spans (#1131) 2020-10-09 19:05:09 +10:00
Jane Lusby 855f9b5bcb
Implement MVP of NonFinalizedState and integrate it with the state service (#1101)
* implement most of the chain functions
* implement fork
* fix outpoint handling in Chain struct
* update expect for work
* split utxo into two sets
* update the Chain definition
* remove allow attribute in zebra-state/lib.rs
* merge ChainSet type into MemoryState
* Add error messages to asserts
* export proptest impls for use in downstream crates
* add testjob for disabled feature in zebra-chain
* try to fix github actions syntax
* add module doc comment
* update RFC for utxos
* add missing header
* working proptest for Chain
* propagate back results over channel
* Start updating RFC to match changes
* implement queued block pruning
* and now it syncs wooo!
* remove empty modules
* setup config for proptests
* re-enable missing_docs lint
* update RFC to match changes in impl
* add documentation
* use more explicit variable names
2020-10-08 13:07:32 +10:00