microsoft / CCF

Confidential Consortium Framework
https://microsoft.github.io/CCF/
Apache License 2.0
777 stars 211 forks source link

Expose a way for indexing strategies to obtain the signature and inclusion proof. #4247

Closed plietar closed 1 year ago

plietar commented 2 years ago

Is your feature request related to a problem? Please describe. When a transaction is committed, indexing strategies receive a call back that allow them to cache the new KVs in a way that is practical for retrieval without iteration over the entire ledger. However, there is currently no way to cache the receipt associated with the transaction. I currently have to use a historical query anytime I want to get the receipt.

The receipt can of course not be computed in the call back itself, since the signature and merkle tree is part of a later transaction.

Describe the solution you'd like When a signature transaction happens, I'd like the indexing strategy to receive a call back, in which it could extract the inclusion proof for any transaction that happened since the previous signature. For this, my indexer would keep track of what transaction it is interested in finding a receipt for.

In pseudo-code, my indexer would look like this:

TxID last_commit;
Receipt last_receipt;

void handle_committed_transaction(TxID tx_id, const ReadOnlyStorePtr& store) {
  auto tx = store->create_read_only_tx();
  if (tx.template<MyTable>ro()->get().has_value()) { // A new value was written to the singleton table MyTable
    last_commit = tx_id;
  }

  if (has_signature(tx)) {
    auto sig = get_signature(tx);
    auto proof = get_inclusion_proof(tx, last_commit);
    auto evidence = get_commit_evidence(last_commit);
    last_receipt = construct_receipt(sig, proof, evidence);
  }
}

Describe alternatives you've considered Alternatively, in the initial call to handle_committed_transaction, CCF could provide a way for indexers to scan forward in the ledger to find the next signature. This is potentially expensive, so it is IMO simpler for the indexer to wait for the signature transaction to arrive.

Additional context There is some concern about caching too many receipts, since there is a lot of duplicated information in the inclusion proofs. For my use case, I will only ever be caching a single receipt so it shouldn't be an issue.

achamayou commented 2 years ago

As discussed, another, more efficient change would be to expose the following APIs:

  1. An API allowing historical queries to derive the commit evidence for a given TxID
  2. An API allowing an indexer (or any context with a ro Tx on a signature transaction) to extract a path to a TxID that precedes it (but follows the previous signature).

This is sufficient for the kind of indexing you need to do, but would not create additional costs for the vast majority of transactions for which receipt generation is not necessary/wanted.

achamayou commented 1 year ago

@plietar we would gladly take a PR for the APIs listed above.

achamayou commented 1 year ago

Not under active consideration.