Skip to content

Commit

Permalink
add storage proofs
Browse files Browse the repository at this point in the history
  • Loading branch information
chris124567 committed May 15, 2024
1 parent d6e25a8 commit fe614d7
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 3 deletions.
1 change: 1 addition & 0 deletions explorer/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ type Transaction struct {
SiafundOutputs []SiafundOutput `json:"siafundOutputs,omitempty"`
FileContracts []FileContract `json:"fileContracts,omitempty"`
FileContractRevisions []FileContractRevision `json:"fileContractRevisions,omitempty"`
StorageProofs []types.StorageProof `json:"storageProofs,omitempty"`
MinerFees []types.Currency `json:"minerFees,omitempty"`
ArbitraryData [][]byte `json:"arbitraryData,omitempty"`
Signatures []types.TransactionSignature `json:"signatures,omitempty"`
Expand Down
17 changes: 17 additions & 0 deletions persist/sqlite/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,21 @@ func addFileContractRevisions(tx *txn, id int64, txn types.Transaction, dbIDs ma
return nil
}

func addStorageProofs(tx *txn, id int64, txn types.Transaction) error {
stmt, err := tx.Prepare(`INSERT INTO transaction_storage_proofs(transaction_id, transaction_order, parent_id, leaf, proof) VALUES (?, ?, ?, ?, ?)`)
if err != nil {
return fmt.Errorf("addStorageProofs: failed to prepare statement: %w", err)
}
defer stmt.Close()

for i, proof := range txn.StorageProofs {
if _, err := stmt.Exec(id, i, encode(proof.ParentID), proof.Leaf[:], encode(proof.Proof)); err != nil {
return fmt.Errorf("addStorageProofs: failed to execute statement: %w", err)
}
}
return nil
}

func addTransactions(tx *txn, bid types.BlockID, txns []types.Transaction, scDBIds map[types.SiacoinOutputID]int64, sfDBIds map[types.SiafundOutputID]int64, fcDBIds map[explorer.DBFileContract]int64) error {
checkTransactionStmt, err := tx.Prepare(`SELECT id FROM transactions WHERE transaction_id = ?`)
if err != nil {
Expand Down Expand Up @@ -310,6 +325,8 @@ func addTransactions(tx *txn, bid types.BlockID, txns []types.Transaction, scDBI
return fmt.Errorf("failed to add file contract: %w", err)
} else if err := addFileContractRevisions(tx, txnID, txn, fcDBIds); err != nil {
return fmt.Errorf("failed to add file contract revisions: %w", err)
} else if err := addStorageProofs(tx, txnID, txn); err != nil {
return fmt.Errorf("failed to add storage proofs: %w", err)
}
}
return nil
Expand Down
16 changes: 15 additions & 1 deletion persist/sqlite/encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ func encode(obj any) any {
obj.EncodeTo(e)
e.Flush()
return buf.Bytes()
case []types.Hash256:
var buf bytes.Buffer
e := types.NewEncoder(&buf)
e.WritePrefix(len(obj))
for _, o := range obj {
o.EncodeTo(e)
}
e.Flush()
return buf.Bytes()
case uint64:
b := make([]byte, 8)
binary.BigEndian.PutUint64(b, obj)
Expand Down Expand Up @@ -58,7 +67,12 @@ func (d *decodable) Scan(src any) error {
case types.DecoderFrom:
dec := types.NewBufDecoder(src)
v.DecodeFrom(dec)
return dec.Err()
case *[]types.Hash256:
dec := types.NewBufDecoder(src)
*v = make([]types.Hash256, dec.ReadPrefix())
for i := range *v {
(*v)[i].DecodeFrom(dec)
}
case *uint64:
*v = binary.BigEndian.Uint64(src)
default:
Expand Down
11 changes: 11 additions & 0 deletions persist/sqlite/init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,17 @@ CREATE TABLE transaction_signatures (

CREATE INDEX transaction_signatures_transaction_id_index ON transaction_signatures(transaction_id);

CREATE TABLE transaction_storage_proofs (
transaction_id INTEGER REFERENCES transactions(id) ON DELETE CASCADE NOT NULL,
transaction_order INTEGER NOT NULL,
parent_id BLOB REFERENCES last_contract_revision(contract_id) ON DELETE CASCADE NOT NULL,
leaf BLOB NOT NULL,
proof BLOB NOT NULL,
UNIQUE(transaction_id, transaction_order)
);

CREATE INDEX transaction_storage_proofs_transaction_id_index ON transaction_storage_proofs(transaction_id);

CREATE TABLE transaction_siacoin_inputs (
transaction_id INTEGER REFERENCES transactions(id) ON DELETE CASCADE NOT NULL,
transaction_order INTEGER NOT NULL,
Expand Down
31 changes: 29 additions & 2 deletions persist/sqlite/transactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,30 @@ ORDER BY ts.transaction_order ASC`
return result, nil
}

// transactionStorageProofs returns the storage proofs for each transaction.
func transactionStorageProofs(tx *txn, txnIDs []int64) (map[int64][]types.StorageProof, error) {
query := `SELECT transaction_id, parent_id, leaf, proof
FROM transaction_storage_proofs
WHERE transaction_id IN (` + queryPlaceHolders(len(txnIDs)) + `)
ORDER BY transaction_order ASC`
rows, err := tx.Query(query, queryArgs(txnIDs)...)
if err != nil {
return nil, err
}
defer rows.Close()

result := make(map[int64][]types.StorageProof)
for rows.Next() {
var txnID int64
var proof types.StorageProof
if err := rows.Scan(&txnID, decode(&proof.ParentID), &proof.Leaf, decode(&proof.Proof)); err != nil {
return nil, fmt.Errorf("failed to scan arbitrary data: %w", err)
}
result[txnID] = append(result[txnID], proof)
}
return result, nil
}

// blockTransactionIDs returns the database ID for each transaction in the
// block.
func blockTransactionIDs(tx *txn, blockID types.BlockID) (dbIDs []int64, err error) {
Expand Down Expand Up @@ -441,8 +465,10 @@ func (s *Store) getTransactions(tx *txn, dbIDs []int64) ([]explorer.Transaction,
return nil, fmt.Errorf("getTransactions: failed to get file contract revisions: %w", err)
}

// TODO: storage proofs
// TODO: signatures
txnStorageProofs, err := transactionStorageProofs(tx, dbIDs)
if err != nil {
return nil, fmt.Errorf("getTransactions: failed to get storage proofs: %w", err)
}

var results []explorer.Transaction
for _, dbID := range dbIDs {
Expand All @@ -453,6 +479,7 @@ func (s *Store) getTransactions(tx *txn, dbIDs []int64) ([]explorer.Transaction,
SiafundOutputs: txnSiafundOutputs[dbID],
FileContracts: txnFileContracts[dbID],
FileContractRevisions: txnFileContractRevisions[dbID],
StorageProofs: txnStorageProofs[dbID],
MinerFees: txnMinerFees[dbID],
ArbitraryData: txnArbitraryData[dbID],
Signatures: txnSignatures[dbID],
Expand Down

0 comments on commit fe614d7

Please sign in to comment.