github zingolabs/zaino 0.10.1

3 hours ago

Release 0.10.1, cut from dev at 702f6b9 and merged to stable in #1629. Crate versions are derived from the changesets that landed since 0.10.0; breaking changes take a minor bump under 0.x.

Crate versions

Crate 0.10.0 cycle 0.10.1 cycle
zainod 0.10.0 0.10.1
zaino-serve 0.8.0 0.9.0
zaino-state 0.9.0 0.10.0
zaino-proto 0.6.0 0.6.1
zaino-primitives 0.2.1 0.3.0
zaino-rpc 0.2.1 0.3.0
zaino-source 0.2.1 0.2.2
zaino-source-zebra 0.2.1 0.2.2
zaino-source-zebra-rpc 0.2.1 0.2.2
zaino-source-zebra-readstate 0.2.1 0.2.2
zaino-source-macros 0.1.0 0.1.1
zaino-convert-zebra 0.2.1 0.3.0
zaino-consensus 0.1.1 0.2.0
zaino-mempool 0.2.1 0.2.2
zaino-mempool-service 0.2.1 0.2.2
zaino-chain-head 0.1.1 0.2.0
zaino-chain-head-service 0.1.1 0.2.0
zaino-chain-store 0.1.0 0.1.1
zaino-chain-store-zainodb 0.1.0 0.2.0
zaino-address 0.1.1 0.1.2
zaino-common 0.5.2 0.5.3
zaino-encoding 0.1.0 0.1.1
zaino-status 0.1.1 0.1.2

Bold: the crate carries a breaking change; see its migration notes below. Docker images: zingodevops/zaino:0.10.1 and zingodevops/zaino:0.10.1-no-tls (also under zingodevops/zainod). All crates are on crates.io.

Changes by crate

zainod 0.10.1

Added

  • The gRPC server offers zaino.index.v1.IndexedTipService, a Zaino extension that lets a client wait for a newly indexed block without polling. The lightwalletd protocol is unchanged.
  • The metrics listener (metrics_endpoint) runs on its own thread and runtime and also serves /livez (fails once the indexer loop stops reporting for 30s).
  • Graceful shutdown on SIGTERM, through the same close path as an internal shutdown.
  • Process metrics (process_cpu_seconds_total, process_resident_memory_bytes, fds, threads) sampled on scrape, zainod.restarts_total, and explicit bucket ladders for every histogram (none scrape as summaries any more).

Changed

  • dependency zaino-chain-head-service 0.1.1→0.2.0 crossed the requirement ^0.1.1
  • dependency zaino-rpc 0.2.1→0.3.0 crossed the requirement ^0.2.1
  • dependency zaino-serve 0.8.0→0.9.0 crossed the requirement ^0.8.0
  • dependency zaino-state 0.9.0→0.10.0 crossed the requirement ^0.9.0

Fixed

  • A metrics_endpoint configured on a binary built without prometheus now warns instead of being silently ignored; a non-private bind warns that the listener is unauthenticated.
  • A metrics_endpoint that fails to bind now fails startup with the error, instead of leaving the process running with no /metrics, no /livez, and no upkeep of the recorder's histogram samples. The listener is bound before the recorder is installed.

zaino-serve 0.9.0

Added

  • Serve IndexedTipService/SubscribeIndexedTips on the gRPC server. A subscription first receives the current indexed tip, then each canonical tip change, including a same-height reorg. A slow client receives only the latest tip, and graceful shutdown ends open subscriptions.
  • JSON-RPC serving metrics zaino.jsonrpc.request_duration_seconds{method} and zaino.jsonrpc.errors_total{method,code}; unregistered method names are labelled unknown.

Changed

  • BlockDeltas::from_domain and the getblockchaininfo pool-balance rendering are infallible, because the domain types already guarantee the range. The DeltaAmountOutOfRange and PoolBalanceOutOfRange errors are removed.
    Migration: Remove handling for DeltaAmountOutOfRange and PoolBalanceOutOfRange, and drop the ? on the now-infallible conversions.
  • Removed zaino.grpc.requests_total (= zaino.grpc.request_duration_seconds _count); zaino.grpc.errors_total{code} now carries the status name (NotFound). Feature prometheus removed.
    Migration: Use zaino.grpc.request_duration_seconds_count for request volume.
  • dependency zaino-consensus 0.1.1→0.2.0 crossed the requirement ^0.1.1
  • dependency zaino-primitives 0.2.1→0.3.0 crossed the requirement ^0.2.1
  • dependency zaino-state 0.9.0→0.10.0 crossed the requirement ^0.9.0

Fixed

  • Confirmation counts in verbose blocks, verbose headers, block deltas and transaction outputs are checked: a value below -1, a block value of 0, or a count past u32 is rejected instead of passed through.
  • getaddressdeltas rejects an invalid address as invalid params instead of admitting it.
  • z_gettreestate writes the Orchard and Ironwood finalRoot in display order. Only the Sapling root is byte-reversed for display, so both pools previously named a root no chain ever had.
  • getblockchaininfo renders chainSupply with its value; every backend previously reported it as zero.

Internal

  • The block-header render test builds its chainwork from a compile-time constant.

zaino-state 0.10.0

Added

  • Add a stream of indexed-tip changes, driven by the existing watch notifications instead of polling.

Changed

  • Sync-loop metrics: added zaino.sync.consecutive_failures and zaino.sync.backoff_seconds.
    Migration: Removed metrics: zaino.sync.lag_blocks (derive zaino.chain.tip_height - zaino.sync.finalized_height), iterations_total, iteration_duration_seconds, errors_total, has_reached_tip, reached_tip_at. Feature prometheus removed.
  • dependency zaino-chain-head 0.1.1→0.2.0 crossed the requirement ^0.1.1
  • dependency zaino-chain-head-service 0.1.1→0.2.0 crossed the requirement ^0.1.1
  • dependency zaino-chain-store-zainodb 0.1.0→0.2.0 crossed the requirement ^0.1.0
  • dependency zaino-consensus 0.1.1→0.2.0 crossed the requirement ^0.1.1
  • dependency zaino-convert-zebra 0.2.1→0.3.0 crossed the requirement ^0.2.1
  • dependency zaino-primitives 0.2.1→0.3.0 crossed the requirement ^0.2.1
  • dependency zaino-rpc 0.2.1→0.3.0 crossed the requirement ^0.2.1

Fixed

  • An address's net value no longer rejects busy address history as corrupt. Gross receipts and spends may exceed the supply; only an impossible net value is refused.
  • getrawtransaction in verbose mode reports time and blocktime from the containing block's header.

Internal

  • Confirmation counts use the exact confirmation state types.
  • Transparent addresses are constructed through the validating constructor.
  • Chain-head blocks converted for serving now carry no chain work, instead of reinterpreting the window's anchor-relative total as an absolute one.
    • The chain-index proptests run against a persistent finalised state and wait for it to finish building; they no longer exercise ephemeral mode.
  • Generated chains are relinked (merkle root and parent hash) so the finalised state's write-path checks accept them, which also re-enables make_chain.
  • Test-only: the chain-head test builds block work through SingleBlockWork::new, and the orphaned golden module that no mod declaration named is deleted.

zaino-proto 0.6.1

Added

  • Add the zaino.index.v1.IndexedTipService protocol with the SubscribeIndexedTips server-streaming call.

zaino-primitives 0.3.0

Added

  • Add RelativeChainWork, the proof-of-work total a run of blocks holds, measured from where the run begins rather than from genesis.
  • types::TransparentAddressKey — how an index keys a transparent output: a 20-byte hash and the script form it came from. Shared vocabulary, because both halves of an address's history key by it and a consumer merging them must not have to translate. from_script shares classify_script, so a store indexing an output and a chain head reporting on one cannot classify it differently.

Changed

  • Zatoshi quantities are three checked types: Zatoshis (an amount, 0 ..= supply), ZatoshisFlowSum (an accumulation of movements, bounded only by u128), and SignedZatoshis (a movement or a net, -supply ..= supply). accumulate, sum_balances and ZatoshisFlowSum::net are the only arithmetic, and AddressBalance.received is a ZatoshisFlowSum. (#1504, #1505)
    Migration: SignedZatoshis::new(i64) is removed: parse a value with SignedZatoshis::try_new, or derive one with ZatoshisFlowSum::net. Read AddressBalance.received as a ZatoshisFlowSum, since lifetime receipts can exceed the supply.
  • The Confirmations = i64 alias is replaced by BlockConfirmations (NotInBestChain or Confirmed(NonZeroU32)) and TxConfirmations (Mempool or Mined(BlockConfirmations)). Each type converts to and from the RPC integer with to_rpc_i64 and try_from_rpc_i64.
    Migration: Replace sign checks on the integer with the enum variants or is_in_best_chain. Build a best-chain block's value with BlockConfirmations::of_best_chain_block(height, tip).
  • TransparentAddress is validated at construction: try_new accepts only P2PKH and P2SH addresses of any Zcash network and rejects other kinds with a typed TransparentAddressError. network() returns the new AddressNetwork, and script_type() returns the address's ScriptType.
    Migration: Replace TransparentAddress::new with TransparentAddress::try_new and handle TransparentAddressError.
  • Chain work is two types: AbsoluteChainWork, the cumulative work from genesis, and SingleBlockWork, one block's contribution, with genesis, accumulate and rollback operations. Each work error is defined in the module that raises it.
    Migration: Replace the single chain-work type with AbsoluteChainWork for totals and SingleBlockWork for one block's work.
  • TreeSize is a checked newtype backed by u32. TreeRootInfo, BlockTreeSizes and ChainMetadata use it in place of u64 and u32 fields, and an oversized value is refused instead of truncated. ChainMetadata::ZERO and ChainMetadata::new are added. (#549)
    Migration: Build tree sizes with TreeSize::from(u32) or its checked constructor, and read them through TreeSize.
  • CompactDifficulty is validated at construction and computes work natively (nBits to target to work). A valid but very small target reports a typed WorkOverWidth instead of panicking.
    Migration: Construct difficulty values through CompactDifficulty's checked constructor and handle CompactDifficultyError.
  • EncryptedCiphertext is renamed CompactCiphertext, because it holds only the 52-byte compact prefix. It is a [u8; 52] behind an exact-length try_new.
    Migration: Rename EncryptedCiphertext to CompactCiphertext, and construct it with try_new from exactly 52 bytes.
  • SingleBlockWork::new takes a NonZeroU128 and is infallible; SingleBlockWork::try_new and ZeroWork are removed.
    Migration: Prove the value non-zero before the call: SingleBlockWork::new(NonZeroU128::new(work).expect(...)) or, for a literal, a const evaluated at compile time. Handle a zero where the integer is produced; the constructor no longer reports it.
  • AbsoluteChainWork::try_from_reported and ChainWorkOverWidth are removed; no validator Zaino reads reports chainwork, so no wire value converts into the type. to_be_bytes and a new from_be_bytes, with ChainWorkBytesError, are the one definition of the 32-byte form.
    Migration: Build an AbsoluteChainWork from a NonZeroU128 through new, or fold it from SingleBlockWork values. Read 32 stored bytes with from_be_bytes, which refuses an over-width or all-zero value; there is no absence case.

zaino-rpc 0.3.0

Changed

  • RpcClient::call / call_with_timeout take method: &'static str (bounds metric-label cardinality). Outbound metrics are now zaino.rpc.outbound.duration_seconds{method} and zaino.rpc.outbound.errors_total{method,outcome} (transport_error, rpc_error, retried).
    Migration: Pass method names as string literals. Removed metrics: zaino.rpc.outbound.requests_total, request_duration_seconds, retries_total. Feature prometheus removed.

zaino-source 0.2.2

Added

  • OneShotGetCommitmentTreeRootsByHeight, with its resilient twin GetCommitmentTreeRootsByHeight: tree roots at the best-chain block at a height, answering with the block's hash alongside the roots. The hash names which block answered, so a consumer pairing this query with a concurrent hash-addressed read can detect a reorg between the two.

Changed

  • dependency zaino-primitives 0.2.1→0.3.0 crossed the requirement ^0.2.1

Internal

  • Tree sizes use the checked TreeSize type.
  • Difficulty and ciphertexts use the checked zaino-primitives types.

zaino-source-zebra 0.2.2

Changed

  • dependency zaino-primitives 0.2.1→0.3.0 crossed the requirement ^0.2.1

zaino-source-zebra-rpc 0.2.2

Changed

  • dependency zaino-convert-zebra 0.2.1→0.3.0 crossed the requirement ^0.2.1
  • dependency zaino-primitives 0.2.1→0.3.0 crossed the requirement ^0.2.1
  • dependency zaino-rpc 0.2.1→0.3.0 crossed the requirement ^0.2.1

Fixed

  • A signed zatoshi value outside -supply ..= supply in a validator reply fails as a typed parse error.
  • Confirmation counts from the validator are parsed into the exact confirmation states and rejected when invalid.
  • Transparent addresses from the validator are validated, with a typed error for an invalid one.
  • The unnamed chainSupply total in a getblockchaininfo reply keeps its value.
  • The chainwork fields of getblockheader, getblock, and getblockchaininfo are no longer parsed and read as None; Zebra omits or zeroes them, and a reply without the key no longer fails.

Internal

  • Adapter call helpers take &'static str method names, following zaino-rpc.

zaino-source-zebra-readstate 0.2.2

Changed

  • dependency zaino-convert-zebra 0.2.1→0.3.0 crossed the requirement ^0.2.1
  • dependency zaino-primitives 0.2.1→0.3.0 crossed the requirement ^0.2.1

Fixed

  • A signed zatoshi value outside -supply ..= supply in the read state fails as a typed parse error.
  • Transparent addresses from the read state are validated, with a typed error for an invalid one.
  • getblockchaininfo reports the transparent, lockbox and ironwood pools, so the Ironwood pool no longer reads as empty across NU6.3 activation. chainSupply is the total over every pool, not the transparent balance.

Internal

  • Confirmation counts use the exact confirmation state types.

zaino-source-macros 0.1.1

Internal

  • The published package carries a README, keywords and categories.
  • The macros build on syn 3.

zaino-convert-zebra 0.3.0

Changed

  • transaction_from_zebra takes only the transaction; a transaction's position, and whether it is the coinbase, now comes from its order in the block. ConvertError gains a Block variant for converted transactions that do not form a valid block.
    Migration: Drop the position argument from transaction_from_zebra calls, and match ConvertError::Block.
  • ConvertError gains Difficulty and Ciphertext variants. A ciphertext shorter than the compact prefix is a typed error instead of a panic.
    Migration: Match ConvertError::Difficulty and ConvertError::Ciphertext.
  • dependency zaino-primitives 0.2.1→0.3.0 crossed the requirement ^0.2.1

zaino-consensus 0.2.0

Changed

  • work_from_bits, WorkError and the work module are removed; zaino-primitives owns the one native difficulty pipeline.
    Migration: Compute work through zaino_primitives' CompactDifficulty.

zaino-mempool 0.2.2

Changed

  • dependency zaino-primitives 0.2.1→0.3.0 crossed the requirement ^0.2.1

zaino-mempool-service 0.2.2

Added

  • Poll-loop metrics zaino.mempool.transactions, zaino.mempool.bytes{kind}, zaino.mempool.unadmitted, zaino.mempool.poll_seconds.

Changed

  • dependency zaino-primitives 0.2.1→0.3.0 crossed the requirement ^0.2.1

zaino-chain-head 0.2.0

Added

  • ChainHeadBlockSource is a bound alias over six zaino-source ports, not five: it now also requires OneShotGetCommitmentTreeRootsByHeight. A source that implements the bound by hand must answer the new port.

Changed

  • ChainHeadWork is removed; a retained block's work is now a RelativeChainWork from zaino-primitives, measured from the anchor rather than from the anchor's parent.
    Migration: Replace ChainHeadWork with zaino_primitives::types::RelativeChainWork. ChainHeadWork::as_u128 has no replacement: an anchor-relative total cannot be converted to an absolute chain work, which is what that method allowed. The anchor's own work is now RelativeChainWork::ZERO, so a window's totals are each one block's work lower than before; comparisons between them are unaffected.
  • dependency zaino-consensus 0.1.1→0.2.0 crossed the requirement ^0.1.1
  • dependency zaino-primitives 0.2.1→0.3.0 crossed the requirement ^0.2.1

Internal

  • Block work uses the zaino-primitives chain-work types.

zaino-chain-head-service 0.2.0

Added

  • The catch-up walk fetches each block and its tree roots concurrently, through the height-addressed OneShotGetCommitmentTreeRootsByHeight port. The two reads can straddle a reorg, so the walk compares the hash that the roots answer names against the block it fetched, and refetches the roots by hash on a mismatch.

Changed

  • ChainHeadAdvanceError::SourceUnavailable carries the source's FetchError instead of a String, so Error::source() returns the transport cause and its FailureMode. A rejected query stays under InconsistentSource, naming the query.
    Migration: Match SourceUnavailable(fetch_error) and format the error with Display where a message was read from the String.
  • The prometheus feature and the implicit metrics feature are removed; reorg metrics are always emitted and cost nothing without an installed recorder.
    Migration: Remove prometheus or metrics from this crate's feature list in dependent manifests.
  • dependency zaino-chain-head 0.1.1→0.2.0 crossed the requirement ^0.1.1
  • dependency zaino-primitives 0.2.1→0.3.0 crossed the requirement ^0.2.1

Fixed

  • The chain head now follows the validator when its tip moves to a lower block. Previously a retained block with more work pulled the tip back up, so a rollback was never followed. A heavier retained block is now logged as a warning instead.
  • After a rollback or a reorg onto a shorter branch, heights above the new tip are no longer reported as part of the best chain. The blocks there stay available as a competing branch.
  • A block from the validator that does not attach directly to the chain head's tip (wrong height or wrong parent) now fails the update as inconsistent validator data, instead of being added to the best chain.
  • Reorg handling and reorg detection no longer recurse once per block. A reorg deeper than roughly 130 blocks, or a validator rollback below the retained window, overflowed the stack and aborted the process; both now walk iteratively and terminate at the retained window. (#1551)
  • Every block that crosses the consensus seam is handed off to the freeze stream. Trimming ran before the handoff read the blocks it emits, so an iteration advancing the tip by more than eleven blocks settled blocks it never handed off, and reported nothing.
  • The chain head follows the validator's tip, including a tip that rolls back, and refuses a block labelled with a height other than the next one. Before, the heaviest retained block won and a mislabelled block joined the best chain. The previous rule stays as a crate-private policy, TipSelection::HeaviestRetained.
  • zaino.sync.reorg_total / reorg_depth now count reorgs won by a longer chain (previously missed by a height comparison); depth = blocks rewritten back to the fork point. An old tip that an advance pushed below the retained window, or that a re-anchor dropped, is an advance and not a reorg; only an old tip still inside the window counts as a reorg of unknown depth. Feature prometheus removed; emission is unconditional.

Internal

  • The in-memory chain head stores its tip block separately from the other retained blocks, so it can never be empty.
  • The snapshot keeps its own invariants in the type: the tip is a field, so the graph is never empty; a block becomes canonical only as a checked child of the tip; a branch switch rewinds to the fork point first. A crate-private ChainGraph contract, with a model-based property test, runs against every implementation.
  • The snapshot's tip lookup goes through a single tip_block accessor. (#1482)
  • Value balances use the checked zatoshi quantity types.
  • Fold a window's work from RelativeChainWork::ZERO at the anchor. A work overflow while extending the window is reported as ChainHeadAdvanceError::InconsistentSource rather than ReorgFailure.
  • The extending block's work is proven non-zero on the NonZeroU128 step before SingleBlockWork::new, with the same error message as before.

zaino-chain-store 0.1.1

Changed

  • dependency zaino-primitives 0.2.1→0.3.0 crossed the requirement ^0.2.1

Internal

  • Address balances use the checked zatoshi quantity types.

zaino-chain-store-zainodb 0.2.0

Changed

  • The crate's own chain-work type is replaced by a re-export of the zaino-primitives type. The on-disk format is unchanged.
    Migration: Import chain work from zaino_primitives.

  • The crate's difficulty wrapper and its ciphertext pad-or-truncate helpers are removed in favour of the zaino-primitives types.
    Migration: Use zaino_primitives' CompactDifficulty and CompactCiphertext.

    • BlockContext, BlockHeaderData and IndexedBlock take a Work parameter: AbsoluteChainWork or Option (default).
  • Only the AbsoluteChainWork form has a stored encoding.

  • DbWrite::write_block takes IndexedBlock.

  • StoredBlockRead answers from the v1 backend only.

  • On-disk format unchanged.
    Migration: - BlockContext::new and conversion::indexed_block take the chainwork in either form.

  • indexed_block_from_stored yields IndexedBlock; widen with map_chainwork(Some).

  • Chain-head blocks carry None and do not type-check against the writer.

  • Sync and store metrics reworked. Added: zaino.sync.fetched_height, block_fetch_seconds, treestate_fetch_seconds, block_assemble_seconds, batch_write_seconds, fsync_seconds, batch_blocks, accumulator_seconds{mode}, accumulator_height, zaino.sync.fetched_{transactions,transparent_inputs,transparent_outputs,sapling_spends,sapling_outputs,orchard_actions,ironwood_actions}_total, zaino.db.validated_height, validation_seconds, on_demand_validations_total, map_size_bytes, used_bytes, zaino.migration.progress_height. zaino.sync.finalized_height now means committed and fsynced.
    Migration: Removed: zaino.sync.block_build_seconds (sum of the three per-block spans), zaino.sync.block_write_seconds (→ batch_write_seconds + fsync_seconds), zaino.sync.{transactions,sapling_outputs,orchard_actions}_total (→ fetched_*_total), zaino.sync.last_block_written_at, zaino.db.tip_height (→ zaino.sync.finalized_height), zaino.db.finalised_ephemeral, zaino.db.accumulator_built_height (→ zaino.sync.accumulator_height), zaino.db.accumulator_rebuild_active (rebuild progress is logged). Throughput counters count fetched blocks: a failed commit or restart re-counts. Feature prometheus removed; emission is unconditional (no-op without a recorder).

  • FinalisedStateMode::EphemeralRouted split into EphemeralSyncing and EphemeralMigrating.
    Migration: Match both new variants wherever EphemeralRouted was matched.

  • dependency zaino-primitives 0.2.1→0.3.0 crossed the requirement ^0.2.1

Fixed

  • A signed zatoshi value outside -supply ..= supply read from disk fails as a typed error.
    • chainwork_from_parent takes the block's height; genesis seeds its own work, an unknown parent above genesis is ParentChainWorkUnknown.
  • chainwork_from_parent_if_known maps that error to None for the zebra-block builder.
  • A missing parent chainwork is StoreError::DataUnavailable on every build path.

Internal

  • The persistent chainwork row is written from the primitive's wire render and read back through its integer, with the width and non-zero checks at the store boundary. The on-disk format is unchanged.

zaino-address 0.1.2

Internal

  • The packaged lockfile picks up the workspace's minor and patch dependency updates.

zaino-common 0.5.3

Internal

  • The packaged lockfile picks up the workspace's minor and patch dependency updates.

zaino-encoding 0.1.1

Internal

  • The published package carries a README, keywords and categories.

zaino-status 0.1.2

Internal

  • The published package carries a README, keywords and categories.

Don't miss a new zaino release

NewReleases is sending notifications on new releases.