diff --git a/README.md b/README.md index b09833f7..1a177a6b 100644 --- a/README.md +++ b/README.md @@ -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). \ No newline at end of file diff --git a/tap_core/src/lib.rs b/tap_core/src/lib.rs index bba38d8a..8d40dcf1 100644 --- a/tap_core/src/lib.rs +++ b/tap_core/src/lib.rs @@ -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 diff --git a/tap_core/src/manager/adapters/escrow.rs b/tap_core/src/manager/adapters/escrow.rs index cc73d55e..16375af1 100644 --- a/tap_core/src/manager/adapters/escrow.rs +++ b/tap_core/src/manager/adapters/escrow.rs @@ -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; diff --git a/tap_core/src/manager/adapters/mod.rs b/tap_core/src/manager/adapters/mod.rs index ef88d244..8ba2a9a0 100644 --- a/tap_core/src/manager/adapters/mod.rs +++ b/tap_core/src/manager/adapters/mod.rs @@ -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; diff --git a/tap_core/src/manager/adapters/rav.rs b/tap_core/src/manager/adapters/rav.rs index 3ecac336..3e719b98 100644 --- a/tap_core/src/manager/adapters/rav.rs +++ b/tap_core/src/manager/adapters/rav.rs @@ -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>; } @@ -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; diff --git a/tap_core/src/manager/adapters/receipt.rs b/tap_core/src/manager/adapters/receipt.rs index 48072ea3..92fe2972 100644 --- a/tap_core/src/manager/adapters/receipt.rs +++ b/tap_core/src/manager/adapters/receipt.rs @@ -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`] 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 diff --git a/tap_core/src/manager/context/memory.rs b/tap_core/src/manager/context/memory.rs index a47bd4ab..efee75d0 100644 --- a/tap_core/src/manager/context/memory.rs +++ b/tap_core/src/manager/context/memory.rs @@ -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::*, diff --git a/tap_core/src/manager/context/mod.rs b/tap_core/src/manager/context/mod.rs index 0c3479f9..c9eab141 100644 --- a/tap_core/src/manager/context/mod.rs +++ b/tap_core/src/manager/context/mod.rs @@ -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; diff --git a/tap_core/src/manager/mod.rs b/tap_core/src/manager/mod.rs index b9955619..91dd8ef9 100644 --- a/tap_core/src/manager/mod.rs +++ b/tap_core/src/manager/mod.rs @@ -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 diff --git a/tap_core/src/manager/tap_manager.rs b/tap_core/src/manager/tap_manager.rs index 45351710..e970922a 100644 --- a/tap_core/src/manager/tap_manager.rs +++ b/tap_core/src/manager/tap_manager.rs @@ -164,15 +164,20 @@ impl Manager 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, @@ -223,14 +228,15 @@ impl Manager 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? { @@ -252,7 +258,8 @@ impl Manager 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 diff --git a/tap_core/src/rav.rs b/tap_core/src/rav.rs index 342f6b3d..49847653 100644 --- a/tap_core/src/rav.rs +++ b/tap_core/src/rav.rs @@ -11,11 +11,11 @@ //! //! Every time you have enough receipts to aggregate, you can send another //! RAV request to the aggregator. The aggregator will verify the request and -//! increment the total amount of GRT that has been aggregated. +//! increment the total amount that has been aggregated. //! //! Once the allocation is closed or anytime the user doesn't want to serve -//! anymore(sender considered malicious, not enough GRT to cover the RAV, etc), -//! the user can redeem the RAV on the blockchain and get the aggregated GRT. +//! anymore(sender considered malicious, not enough in escrow to cover the RAV, etc), +//! the user can redeem the RAV on the blockchain and get the aggregated amount. //! //! The system is considered to have minimal trust because you only need to trust //! the sender until you receive the RAV. The value of non-aggregated receipts must @@ -25,15 +25,17 @@ //! //! 1. Create a [`RAVRequest`] with the valid receipts and the previous RAV. //! 2. Send the request to the aggregator. -//! 3. The aggregator will verify the request and increment the total amount of GRT that has been aggregated. +//! 3. The aggregator will verify the request and increment the total amount that +//! has been aggregated. //! 4. The aggregator will return a [`SignedRAV`]. //! 5. Store the [`SignedRAV`]. //! 6. Repeat the process until the allocation is closed. -//! 7. Redeem the RAV on the blockchain and get the aggregated GRT. +//! 7. Redeem the RAV on the blockchain and get the aggregated amount. //! //! # How to create RAV Requests //! -//! Rav requests should be created using the [`crate::manager::Manager::create_rav_request`] function. +//! Rav requests should be created using the +//! [`crate::manager::Manager::create_rav_request`] function. mod request; @@ -61,24 +63,27 @@ sol! { /// Unix Epoch timestamp in nanoseconds (Truncated to 64-bits) /// corresponding to max timestamp from receipt batch aggregated uint64 timestampNs; - /// Aggregated GRT value from receipt batch and any previous RAV provided (truncate to lower bits) + /// Aggregated value from receipt batch and any previous RAV provided + /// (truncate to lower bits) uint128 valueAggregate; } } impl ReceiptAggregateVoucher { - /// Aggregates a batch of validated receipts with optional validated previous RAV, returning a new RAV if all provided items are valid or an error if not. + /// Aggregates a batch of validated receipts with optional validated previous RAV, + /// returning a new RAV if all provided items are valid or an error if not. /// /// # Errors /// - /// Returns [`Error::AggregateOverflow`] if any receipt value causes aggregate value to overflow - /// + /// Returns [`Error::AggregateOverflow`] if any receipt value causes aggregate + /// value to overflow pub fn aggregate_receipts( allocation_id: Address, receipts: &[EIP712SignedMessage], previous_rav: Option>, ) -> crate::Result { - //TODO(#29): When receipts in flight struct in created check that the state of every receipt is OK with all checks complete (relies on #28) + //TODO(#29): When receipts in flight struct in created check that the state + // of every receipt is OK with all checks complete (relies on #28) // If there is a previous RAV get initialize values from it, otherwise get default values let mut timestamp_max = 0u64; let mut value_aggregate = 0u128; diff --git a/tap_core/src/receipt/checks.rs b/tap_core/src/receipt/checks.rs index de8ae5a0..5a990d15 100644 --- a/tap_core/src/receipt/checks.rs +++ b/tap_core/src/receipt/checks.rs @@ -73,7 +73,8 @@ pub trait Check { async fn check(&self, receipt: &ReceiptWithState) -> CheckResult; } -/// CheckBatch is mostly used by the lib to implement checks that transition from one state to another. +/// CheckBatch is mostly used by the lib to implement checks +/// that transition from one state to another. pub trait CheckBatch { fn check_batch( &self, @@ -84,9 +85,11 @@ pub trait CheckBatch { ); } -/// Provides a built-in check to verify that the timestamp of a receipt is greater than a given value. +/// Provides a built-in check to verify that the timestamp of a receipt +/// is greater than a given value. /// -/// This check is stateful, meaning that it can be updated with a new minimum timestamp. +/// This check is stateful, meaning that it can be updated with a new minimum +/// timestamp. #[derive(Debug)] pub struct StatefulTimestampCheck { min_timestamp_ns: RwLock, @@ -120,7 +123,8 @@ impl Check for StatefulTimestampCheck { } } -/// Timestamp Check verifies if the receipt is **greater or equal** than the minimum timestamp provided. +/// Timestamp Check verifies if the receipt is **greater or equal** than the +/// minimum timestamp provided. /// /// Used by the [`crate::manager::Manager`]. pub struct TimestampCheck(pub u64); @@ -150,7 +154,8 @@ impl CheckBatch for TimestampCheck { } } -/// UniqueCheck is a batch check that verifies if any given list of receipts has unique signatures. +/// UniqueCheck is a batch check that verifies if any given list of receipts +/// has unique signatures. /// /// Used by the [`crate::manager::Manager`]. pub struct UniqueCheck; diff --git a/tap_core/src/receipt/received_receipt.rs b/tap_core/src/receipt/received_receipt.rs index 095b0ede..dc32ef1c 100644 --- a/tap_core/src/receipt/received_receipt.rs +++ b/tap_core/src/receipt/received_receipt.rs @@ -26,10 +26,14 @@ pub type ResultReceipt = std::result::Result, ReceiptWith /// Typestate pattern for tracking the state of a receipt /// -/// - The [ `ReceiptState` ] trait represents the different states a receipt can be in. -/// - The [ `Checking` ] state is used to represent a receipt that is currently being checked. -/// - The [ `Failed` ] state is used to represent a receipt that has failed a check or validation. -/// - The [ `AwaitingReserve` ] state is used to represent a receipt that has passed all checks and is +/// - The [ `ReceiptState` ] trait represents the different states a receipt +/// can be in. +/// - The [ `Checking` ] state is used to represent a receipt that is currently +/// being checked. +/// - The [ `Failed` ] state is used to represent a receipt that has failed a +/// check or validation. +/// - The [ `AwaitingReserve` ] state is used to represent a receipt that has +/// passed all checks and is /// awaiting escrow reservation. /// - The [ `Reserved` ] state is used to represent a receipt that has /// successfully reserved escrow. @@ -45,8 +49,11 @@ where } impl ReceiptWithState { - /// Perform the checks implemented by the context and reserve escrow if all checks pass - /// Returns a [`ReceiptWithState`] if successful, otherwise returns a [`ReceiptWithState`] + /// Perform the checks implemented by the context and reserve escrow if + /// all checks pass + /// + /// Returns a [`ReceiptWithState`] if successful, otherwise + /// returns a [`ReceiptWithState`] pub async fn check_and_reserve_escrow( self, context: &E, @@ -78,7 +85,9 @@ impl ReceiptWithState { /// /// # Errors /// - /// Returns [`ReceiptError::CheckFailedToComplete`] if the requested check cannot be comleted in the receipts current internal state. All other checks must be complete before `CheckAndReserveEscrow`. + /// Returns [`ReceiptError::CheckFailedToComplete`] if the requested check + /// cannot be comleted in the receipts current internal state. + /// All other checks must be complete before `CheckAndReserveEscrow`. /// pub async fn perform_checks(&mut self, checks: &[ReceiptCheck]) -> ReceiptResult<()> { for check in checks { diff --git a/tap_core/src/receipt/state.rs b/tap_core/src/receipt/state.rs index ab42e300..38e7e08b 100644 --- a/tap_core/src/receipt/state.rs +++ b/tap_core/src/receipt/state.rs @@ -3,7 +3,8 @@ //! # Receipt State //! -//! These are the implementation of the typestate pattern for tracking the state of a receipt. +//! These are the implementation of the typestate pattern for tracking the +//! state of a receipt. //! The `ReceiptState` trait represents the different states a receipt can be in. use crate::receipt::ReceiptError; @@ -15,11 +16,13 @@ pub struct Checking; /// Failed state represents a receipt that has failed a check or validation. #[derive(Debug, Clone)] pub struct Failed { - /// A list of checks to be completed for the receipt, along with their current result + /// A list of checks to be completed for the receipt, along with their + /// current result pub error: ReceiptError, } -/// AwaitingReserve state represents a receipt that has passed all checks and is awaiting escrow reservation. +/// AwaitingReserve state represents a receipt that has passed all checks +/// and is awaiting escrow reservation. #[derive(Debug, Clone)] pub struct AwaitingReserve; diff --git a/tap_core/src/signed_message.rs b/tap_core/src/signed_message.rs index cd9b7cd6..602c9aa3 100644 --- a/tap_core/src/signed_message.rs +++ b/tap_core/src/signed_message.rs @@ -48,8 +48,12 @@ pub struct EIP712SignedMessage { /// Unique identifier for a message /// -/// The same message may be signed multiple times, but each signature will *NOT* -/// have a unique hash +/// This is equal to the hash of the hash of the contents of a message. This means +/// that two receipts signed by two different signers will have the same id. +/// +/// +/// This cannot be used as a unique identifier for a message, but can be used as a key +/// for a hashmap where the value is the message. #[derive(Debug, Eq, PartialEq, Hash)] pub struct MessageId(pub [u8; 32]); @@ -80,7 +84,7 @@ impl EIP712SignedMessage { /// # Errors /// /// Returns [`crate::Error::SignatureError`] if the recovered address from the - /// signature is not valid equal to `expected_address` + /// signature is not equal to `expected_address` /// pub fn verify(&self, domain_separator: &Eip712Domain, expected_address: Address) -> Result<()> { let recovery_message_hash: [u8; 32] =