Skip to main content

Crate p2panda_store

Crate p2panda_store 

Source
Expand description

Trait definitions and SQLite implementations for persistent stores used by p2panda.

This crate provides generic trait definitions to flexibly express storage and query behaviour for a wide-range of peer-to-peer systems. In the context of p2panda these include an address book for managing transport information related to nodes in a network, an operation store for maintaining append-only log entries, an orderer store to track operation dependencies, and much more. Concrete SQLite database implementations are provided for all store traits, along with a transaction provider for cases when atomicity and consistency are required for a set of database interactions.

§Features

  • Generic trait definitions required to implement p2panda stores
  • SQLite implementations for all p2panda stores
    • Address book for handling node information
    • Cursors for tracking positions in logs
    • Groups for maintaining auth group state
    • Logs for efficient comparison of log-based data types
    • Operations for storing entries in append-only logs
    • Orderer for tracking dependencies in partially-ordered data sets
  • Transaction provider to group related queries for consistency guarantees
  • Database migrations on store creation or during application runtime

§Examples

§Create an in-memory SQLite store

use p2panda_store::SqliteStoreBuilder;
let store = SqliteStoreBuilder::new().build().await?;

§Create and insert a new operation

Here we use the tx! macro provided by p2panda-store to group several queries into a single transaction.

// Acquire a lock on the store for the duration of the read to write cycle.
//
// This is to ensure that the data returned from the `get_latest_entry()` query does not
// become stale before the call to `insert_operation()`.
//
// Here we acquire a store permit, query the latest log entry, associate the topic with
// the log, insert the operation and commit the transaction before dropping the permit.
let operation = tx!(store, {
    let (seq_num, backlink) = <SqliteStore as LogStore<
        Operation<()>,
        VerifyingKey,
        u64,
        u64,
        Hash,
    >>::get_latest_entry_tx(
        &store, &signing_key.verifying_key(), &log_id
    )
    .await?
    .map(|operation| (operation.header.seq_num + 1, Some(operation.hash)))
    .unwrap_or((0, None));

    let mut header = Header {
        version: 1,
        verifying_key: signing_key.verifying_key(),
        signature: None,
        payload_size: body.size(),
        payload_hash: Some(body.hash()),
        timestamp: Timestamp::now(),
        seq_num,
        backlink,
        extensions: (),
    };

    header.sign(&signing_key);
    let hash = header.hash();

    let operation = Operation {
        hash,
        header: header.clone(),
        body: Some(body),
    };

    <SqliteStore as TopicStore<Topic, VerifyingKey, u64>>::associate(
        &store,
        &topic,
        &signing_key.verifying_key(),
        &log_id,
    )
    .await?;

    store
        .insert_operation(&hash, &operation, &log_id)
        .await?;

    operation
});

Modules§

address_book
Node information stores.
cursors
Cursor position stores.
groups
Group state stores.
logs
Append-only log entry stores.
operations
Operation stores.
orderer
Dependency orderer stores.
sqlitesqlite
SQLite database implementation with associated utility functions.
topics
Topic to application data mapping stores.

Macros§

txmacros
Acquire a permit and execute one or more database queries within a single transaction.
tx_unwrapmacros and (test_utils)

Structs§

SqliteStoresqlite
SQLite database with connection pool and transaction provider.
SqliteStoreBuildersqlite
Builder for SqliteStore.

Enums§

SqliteErrorsqlite
Error when interacting with a SQLite store implementation.

Traits§

Transaction
Traits to implement database transaction provider.