Skip to content

Commit

Permalink
docs: update requested changes
Browse files Browse the repository at this point in the history
Signed-off-by: Gustavo Inacio <[email protected]>
  • Loading branch information
gusinacio committed Mar 25, 2024
1 parent cfb5dcb commit cba489f
Show file tree
Hide file tree
Showing 15 changed files with 160 additions and 147 deletions.
58 changes: 40 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,69 @@

## Overview

The TAP (Timeline Aggregation Protocol) facilitates a series of payments from a sender to a receiver, who aggregates these payments into a single payment. This aggregate payment can then be verified on-chain by a payment verifier, reducing the number of transactions and simplifying the payment process.
The TAP (Timeline Aggregation Protocol) facilitates a series of payments from a
sender to a receiver (TAP Receipts), who aggregates these payments into a single
payment (a Receipt Aggregate Voucher, or RAV). This aggregate payment can then be
verified on-chain by a payment verifier, reducing the number of transactions and
simplifying the payment process.

## Key Components

- **Sender:** Initiates the payment.
- **Receiver:** Receives the payment.
- **Signers:** Multiple signers authorized by the sender to sign receipts.
- **State Channel:** A one-way channel opened by the sender with the receiver for sending receipts.
- **State Channel:** A one-way channel opened by the sender with the receiver
for sending receipts.
- **Receipt:** A record of payment sent by the sender to the receiver.
- **ReceiptAggregateVoucher (RAV):** A signed message containing the aggregate value of the receipts.
- **tap_aggregator:** An entity managed by the sender that signs RAV requests.
- **EscrowAccount:** An account created in the blockchain to hold funds for the sender-receiver pair.
- **ReceiptAggregateVoucher (RAV):** A signed message containing the aggregate
value of the receipts.
- **tap_aggregator:** A service managed by the sender that aggregates receipts
on the receiver's request into a signed RAV.
- **EscrowAccount:** An account created in the blockchain to hold funds for
the sender-receiver pair.

## Security Measures

- The protocol uses asymmetric cryptography to sign and verify messages, ensuring the integrity of receipts and RAVs.
- The protocol uses asymmetric cryptography (ECDSA secp256k1) to sign and
verify messages, ensuring the integrity of receipts and RAVs.

## Process

1. **Opening a State Channel:** A state channel is opened via a blockchain contract, creating an EscrowAccount for the sender-receiver pair.
2. **Sending Receipts:** The sender sends receipts to the receiver through the state channel.
3. **Storing Receipts:** The receiver stores the receipts and tracks the aggregate payment.
4. **Creating a RAV Request:** A RAV request consists of a list of receipts and, optionally, the previous RAV.
5. **Signing the RAV:** The receiver sends the RAV request to the tap_aggregator, which signs it into a RAV.
6. **Tracking Aggregate Value:** The receiver tracks the aggregate value and new receipts since the last RAV.
7. **Requesting a New RAV:** The receiver sends new receipts and the last RAV to the tap_aggregator for a new RAV.
8. **Closing the State Channel:** When the allocation period ends, the receiver can send the last RAV to the blockchain and receive payment from the EscrowAccount.
1. **Opening a State Channel:** A state channel is opened via a blockchain
contract, creating an EscrowAccount for the sender-receiver pair.
2. **Sending Receipts:** The sender sends receipts to the receiver through the
state channel.
3. **Storing Receipts:** The receiver stores the receipts and tracks the
aggregate payment.
4. **Creating a RAV Request:** A RAV request consists of a list of receipts and,
optionally, the previous RAV.
5. **Signing the RAV:** The receiver sends the RAV request to the tap_aggregator,
which signs it into a new RAV.
6. **Tracking Aggregate Value:** The receiver tracks the aggregate value and
new receipts since the last RAV.
7. **Requesting a New RAV:** The receiver sends new receipts and the last RAV
to the tap_aggregator for a new RAV.
8. **Closing the State Channel:** When the allocation period ends, the receiver
can send the last RAV to the blockchain and receive payment from the EscrowAccount.

## Performance Considerations

- The primary performance limitations are the time required to verify receipts and network limitations for sending requests to the tap_aggregator.
- The primary performance limitations are the time required to verify receipts
and network limitations for sending requests to the tap_aggregator.

## Use Cases

- The TAP protocol is suitable for systems with sequential operations that are too expensive to redeem individually on-chain. By aggregating operations and redeeming them in one transaction, costs can be reduced.
- The TAP protocol is suitable for systems with sequential operations that are
too expensive to redeem individually on-chain. By aggregating operations
off-chain and redeeming them in one transaction, costs are drastically reduced.

## Compatibility

- The current implementation is for EVM-compatible blockchains, with most of the system being off-chain.
- The current implementation is for EVM-compatible blockchains, with most of the
system being off-chain.

## Contributing

Contributions are welcome! Please submit a pull request or open an issue to discuss potential changes.
Contributions are welcome! Please submit a pull request or open an issue to
discuss potential changes.
Also, make sure to follow the [Contributing Guide](CONTRIBUTING.md).
65 changes: 1 addition & 64 deletions tap_core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,69 +1,6 @@
// Copyright 2023-, Semiotic AI, Inc.
// SPDX-License-Identifier: Apache-2.0

//! # Timeline Aggregation Protocol
//!
//! ## Overview
//!
//! The TAP (Timeline Aggregation Protocol) facilitates a series of payments from
//! a sender to a receiver, who aggregates these payments into a single payment.
//! This aggregate payment can then be verified on-chain by a payment verifier,
//! reducing the number of transactions and simplifying the payment process.
//!
//! ## Key Components
//!
//! - **Sender:** Initiates the payment.
//! - **Receiver:** Receives the payment.
//! - **Signers:** Multiple signers authorized by the sender to sign receipts.
//! - **State Channel:** A one-way channel opened by the sender with the receiver
//! for sending receipts.
//! - **Receipt:** A record of payment sent by the sender to the receiver.
//! - **ReceiptAggregateVoucher (RAV):** A signed message containing the aggregate
//! value of the receipts.
//! - **tap_aggregator:** An entity managed by the sender that signs RAV requests.
//! - **EscrowAccount:** An account created in the blockchain to hold funds for
//! the sender-receiver pair.
//!
//! ## Security Measures
//!
//! - The protocol uses asymmetric cryptography to sign and verify messages,
//! ensuring the integrity of receipts and RAVs.
//!
//! ## Process
//!
//! 1. **Opening a State Channel:** A state channel is opened via a blockchain
//! contract, creating an EscrowAccount for the sender-receiver pair.
//! 2. **Sending Receipts:** The sender sends receipts to the receiver through
//! the state channel.
//! 3. **Storing Receipts:** The receiver stores the receipts and tracks the
//! aggregate payment.
//! 4. **Creating a RAV Request:** A RAV request consists of a list of receipts
//! and, optionally, the previous RAV.
//! 5. **Signing the RAV:** The receiver sends the RAV request to the
//! tap_aggregator, which signs it into a RAV.
//! 6. **Tracking Aggregate Value:** The receiver tracks the aggregate value and
//! new receipts since the last RAV.
//! 7. **Requesting a New RAV:** The receiver sends new receipts and the last
//! RAV to the tap_aggregator for a new RAV.
//! 8. **Closing the State Channel:** When the allocation period ends, the receiver
//! can send the last RAV to the blockchain and receive payment from the EscrowAccount.
//!
//! ## Performance Considerations
//!
//! - The primary performance limitations are the time required to verify receipts
//! and network limitations for sending requests to the tap_aggregator.
//!
//! ## Use Cases
//!
//! - The TAP protocol is suitable for systems with sequential operations that
//! are too expensive to redeem individually on-chain. By aggregating operations
//! and redeeming them in one transaction, costs can be reduced.
//!
//! ## Compatibility
//!
//! - The current implementation is for EVM-compatible blockchains, with most
//! of the system being off-chain.
//!
#![doc = include_str!("../../README.md")]
//! ## Getting started
//!
//! To get started with the TAP protocol, take a look on the [`manager`] module
Expand Down
3 changes: 2 additions & 1 deletion tap_core/src/manager/adapters/escrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ use crate::{
pub trait EscrowHandler: Send + Sync {
/// Defines the user-specified error type.
///
/// This error type should implement the `Error` and `Debug` traits from the standard library.
/// This error type should implement the `Error` and `Debug` traits from
/// the standard library.
/// Errors of this type are returned to the user when an operation fails.
type AdapterError: std::error::Error + std::fmt::Debug + Send + Sync + 'static;

Expand Down
7 changes: 4 additions & 3 deletions tap_core/src/manager/adapters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@

//! Context adapters for the TAP manager.
//!
//! Each adapter should be defined by the user of the library based on their specific storage and verification requirements. This modular design
//! allows for easy integration with various storage solutions and verification procedures, thereby making the library adaptable to a wide range
//! of use cases.
//! Each adapter should be defined by the user of the library based on their
//! specific storage and verification requirements. This modular design
//! allows for easy integration with various storage solutions and verification
//! procedures, thereby making the library adaptable to a wide range of use cases.
mod escrow;
mod rav;
Expand Down
11 changes: 7 additions & 4 deletions tap_core/src/manager/adapters/rav.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@ use crate::rav::SignedRAV;
pub trait RAVStore {
/// Defines the user-specified error type.
///
/// This error type should implement the `Error` and `Debug` traits from the standard library.
/// This error type should implement the `Error` and `Debug` traits from
/// the standard library.
/// Errors of this type are returned to the user when an operation fails.
type AdapterError: std::error::Error + std::fmt::Debug + Send + Sync + 'static;

/// Updates the storage with the latest validated `SignedRAV`.
///
/// This method should be implemented to store the most recent validated `SignedRAV` into your chosen storage system.
/// Any errors that occur during this process should be captured and returned as an `AdapterError`.
/// This method should be implemented to store the most recent validated
/// `SignedRAV` into your chosen storage system. Any errors that occur
/// during this process should be captured and returned as an `AdapterError`.
async fn update_last_rav(&self, rav: SignedRAV) -> Result<(), Self::AdapterError>;
}

Expand All @@ -36,7 +38,8 @@ pub trait RAVStore {
pub trait RAVRead {
/// Defines the user-specified error type.
///
/// This error type should implement the `Error` and `Debug` traits from the standard library.
/// This error type should implement the `Error` and `Debug` traits from
/// the standard library.
/// Errors of this type are returned to the user when an operation fails.
type AdapterError: std::error::Error + std::fmt::Debug + Send + Sync + 'static;

Expand Down
8 changes: 5 additions & 3 deletions tap_core/src/manager/adapters/receipt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,16 @@ pub trait ReceiptDelete {
pub trait ReceiptRead {
/// Defines the user-specified error type.
///
/// This error type should implement the `Error` and `Debug` traits from the standard library.
/// This error type should implement the `Error` and `Debug` traits from
/// the standard library.
/// Errors of this type are returned to the user when an operation fails.
type AdapterError: std::error::Error + std::fmt::Debug + Send + Sync + 'static;

/// Retrieves all [`ReceiptWithState<Checking>`] within a specific timestamp range.
///
/// If a limit is specified, the adapter should return at most that many receipts, while making
/// sure that no receipts are left behind for any timestamp that is returned. Examples:
/// If a limit is specified, the adapter should return at most that many receipts,
/// while making sure that no receipts are left behind for any timestamp that
/// is returned. Examples:
///
/// - If the adapter has 10 receipts for timestamp 100, and 5 receipts for timestamp 200, and
/// the limit is 10, the adapter should return all 10 receipts for timestamp 100, and none for
Expand Down
3 changes: 2 additions & 1 deletion tap_core/src/manager/context/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

//! In-memory context implementation for the TAP manager.
//!
//! This module provides an in-memory implementation of the TAP manager context. It is useful for testing and development purposes.
//! This module provides an in-memory implementation of the TAP manager context.
//! It is useful for testing and development purposes.
use crate::{
manager::adapters::*,
Expand Down
8 changes: 6 additions & 2 deletions tap_core/src/manager/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

//! Context implementations.
//!
//! Contexts are used to store and retrieve data from the TAP manager. They are used to store receipts, escrow, and other data that is required for the manager to function.
//! Currently, there's only one context implementation available, which is the `MemoryContext`. This context is used to store data in memory and is useful for testing and development purposes.
//! Contexts are used to store and retrieve data from the TAP manager.
//! They are used to store receipts, escrow, and other data that is required
//! for the manager to function.
//! Currently, there's only one context implementation available, which is
//! the `MemoryContext`. This context is used to store data in memory and
//! is useful for testing and development purposes.
pub mod memory;
29 changes: 19 additions & 10 deletions tap_core/src/manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,31 @@

//! Point of entry for managing TAP receipts and RAVs.
//!
//! The [`crate::manager`] module provides facilities for managing TAP receipt and RAV validation, as well as storage flow.
//! The [`crate::manager`] module provides facilities for managing TAP receipt
//! and RAV validation, as well as storage flow.
//!
//! This module should be the primary interface for the receiver of funds to verify, store, and manage TAP receipts and RAVs.
//! The [`Manager`] struct within this module allows the user to specify what checks should be performed on receipts, as well as
//! when these checks should occur (either when a receipt is first received, or when it is being added to a RAV request).
//! This module should be the primary interface for the receiver of funds to
//! verify, store, and manage TAP receipts and RAVs.
//! The [`Manager`] struct within this module allows the user to specify what
//! checks should be performed on receipts, as well as
//! when these checks should occur (either when a receipt is first received,
//! or when it is being added to a RAV request).
//!
//! The [`Manager`] uses a context that implements user-defined [`adapters`] for storage handling.
//! This design offers a high degree of flexibility, letting the user define their own behavior for these critical operations.
//! The [`Manager`] uses a context that implements user-defined [`adapters`]
//! for storage handling.
//! This design offers a high degree of flexibility, letting the user define
//! their own behavior for these critical operations.
//!
//! This solution is flexible enough to enable certain methods depending on the context provided. This is important
//! because the context can be customized to include only the necessary adapters for the user's specific use case. For example,
//! if the user wants to use two different applications, one to handle receipt storage and another to handle RAV storage, they
//! This solution is flexible enough to enable certain methods depending on the
//! context provided. This is important because the context can be customized
//! to include only the necessary adapters for the user's specific use case.
//! For example, if the user wants to use two different applications, one to
//! handle receipt storage and another to handle RAV storage, they
//! can create two different contexts with the appropriate adapters.
//!
//! # Adapters
//! There are 6 main adapters that can be implemented to customize the behavior of the [`Manager`].
//! There are 6 main adapters that can be implemented to customize the behavior
//! of the [`Manager`].
//! You can find more information about these adapters in the [`adapters`] module.
//!
//! # Example
Expand Down
31 changes: 19 additions & 12 deletions tap_core/src/manager/tap_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,15 +164,20 @@ impl<E> Manager<E>
where
E: ReceiptRead + RAVRead + EscrowHandler,
{
/// Completes remaining checks on all receipts up to (current time - `timestamp_buffer_ns`). Returns them in
/// two lists (valid receipts and invalid receipts) along with the expected RAV that should be received
/// for aggregating list of valid receipts.
/// Completes remaining checks on all receipts up to
/// (current time - `timestamp_buffer_ns`). Returns them in two lists
/// (valid receipts and invalid receipts) along with the expected RAV that
/// should be received for aggregating list of valid receipts.
///
/// Returns [`Error::AggregateOverflow`] if any receipt value causes aggregate value to overflow while generating expected RAV
/// Returns [`Error::AggregateOverflow`] if any receipt value causes
/// aggregate value to overflow while generating expected RAV
///
/// Returns [`Error::AdapterError`] if unable to fetch previous RAV or if unable to fetch previous receipts
/// Returns [`Error::AdapterError`] if unable to fetch previous RAV or
/// if unable to fetch previous receipts
///
/// Returns [`Error::TimestampRangeError`] if the max timestamp of the previous RAV is greater than the min timestamp. Caused by timestamp buffer being too large, or requests coming too soon.
/// Returns [`Error::TimestampRangeError`] if the max timestamp of the
/// previous RAV is greater than the min timestamp. Caused by timestamp
/// buffer being too large, or requests coming too soon.
///
pub async fn create_rav_request(
&self,
Expand Down Expand Up @@ -223,14 +228,15 @@ impl<E> Manager<E>
where
E: ReceiptDelete + RAVRead,
{
/// Removes obsolete receipts from storage. Obsolete receipts are receipts that are older than the last RAV, and
/// therefore already aggregated into the RAV.
/// This function should be called after a new RAV is received to limit the number of receipts stored.
/// No-op if there is no last RAV.
/// Removes obsolete receipts from storage. Obsolete receipts are receipts
/// that are older than the last RAV, and therefore already aggregated into the RAV.
/// This function should be called after a new RAV is received to limit the
/// number of receipts stored. No-op if there is no last RAV.
///
/// # Errors
///
/// Returns [`Error::AdapterError`] if there are any errors while retrieving last RAV or removing receipts
/// Returns [`Error::AdapterError`] if there are any errors while retrieving
/// last RAV or removing receipts
///
pub async fn remove_obsolete_receipts(&self) -> Result<(), Error> {
match self.get_previous_rav().await? {
Expand All @@ -252,7 +258,8 @@ impl<E> Manager<E>
where
E: ReceiptStore,
{
/// Runs `initial_checks` on `signed_receipt` for initial verification, then stores received receipt.
/// Runs `initial_checks` on `signed_receipt` for initial verification,
/// then stores received receipt.
/// The provided `query_id` will be used as a key when chaecking query appraisal.
///
/// # Errors
Expand Down
Loading

0 comments on commit cba489f

Please sign in to comment.