Skip to content

Provenance

Gennady Laventman edited this page Sep 6, 2020 · 11 revisions

Provenance and Transactions Proofs

Provenance API give user access to key->value history, raw transaction data access and transactions existence proofs, that provide cryptographic proof of transaction existence in ledger.

// Provenance access to historical data and data integrity proofs
type Provenance interface {
	// GetProof returns two proofs - one proves that tx with give id is part of blocks merkle tree (path to root) 
	// and another shortest path in skip list from block that contains transaction to genesis block
	GetProof(txId []byte) (*types.Proof, error)
	// GetHistory return full history for given key in db
	GetHistory(dbName, key string) (HistoryIterator, error)
	// GetTransaction returns transaction envelope by its id
	GetTransaction(txId []byte) (*types.TransactionEnvelope, error)
}

type HistoryIterator interface {
	Next() (*api.HistoricalData, error)
	Close()
}
message Proof {
  BlockHeader header = 1;
  repeated BlockHeader block_proof = 2;
  repeated bytes ledger_proof = 3;
}

GetHistory API provides all values of specific keys over time, including references to transactions that change this key. It is possible form this data, using GetProof and GetTransactions API, to provide proof of change of specific key at specific time.

As we can see here, the API is Blockchain DB installation level API, not single DB level API and it exposed by DBConnector

// DBConnector handle connectivity between sdk and Blockchain Database cluster
type DBConnector interface {
	...
	// GetProvenance returns blockchain db provenance interface
	GetProvenance() Provenance
}

If not mentioned otherwise, this document describes skip list based proofs for ledger consistency and integrity. For more detailed explanation, see Transaction-Proofs-Skiplist

As mentioned in Transaction document, during provenance data creation phase, {Key, newValue, BlockTime, BlockNumber, TxTime, TxId, ClientId, IsDelete, IsOk} tuple stored as provenance data for each key in WSet.

GetHistory returns slice of history values based on data stored in provenance tuple

message HistoricalValue {
  // DB key
  string key = 1;
  // Historical value
  bytes value = 2;
  // Sequencer time when block was created
  google.protobuf.Timestamp blocktime = 3;
  // Transaction that did the change
  bytes txId = 4;
  // Block number that holds changing tx
  uint64 blocknumber = 5;
  // Is this tx deleted this key
  bool isDelete = 6;
}

Access to provenance data

For now, we go with the simplest approach - if user now have read access to given key, it can access its historical data as well, even if it didn't has access to this key in past.

Transaction time

To eliminate difference between client clocks, Transaction time set to be equal to block time. We need to add time to block header.

Clone this wiki locally