Skip to content

Commit

Permalink
add transaction signatures
Browse files Browse the repository at this point in the history
  • Loading branch information
chris124567 committed May 15, 2024
1 parent 1c705ee commit 07ab4cc
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 8 deletions.
17 changes: 9 additions & 8 deletions explorer/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,15 @@ type FileContractRevision struct {

// A Transaction is a transaction that uses the wrapped types above.
type Transaction struct {
SiacoinInputs []types.SiacoinInput `json:"siacoinInputs,omitempty"`
SiacoinOutputs []SiacoinOutput `json:"siacoinOutputs,omitempty"`
SiafundInputs []types.SiafundInput `json:"siafundInputs,omitempty"`
SiafundOutputs []SiafundOutput `json:"siafundOutputs,omitempty"`
FileContracts []FileContract `json:"fileContracts,omitempty"`
FileContractRevisions []FileContractRevision `json:"fileContractRevisions,omitempty"`
MinerFees []types.Currency `json:"minerFees,omitempty"`
ArbitraryData [][]byte `json:"arbitraryData,omitempty"`
SiacoinInputs []types.SiacoinInput `json:"siacoinInputs,omitempty"`
SiacoinOutputs []SiacoinOutput `json:"siacoinOutputs,omitempty"`
SiafundInputs []types.SiafundInput `json:"siafundInputs,omitempty"`
SiafundOutputs []SiafundOutput `json:"siafundOutputs,omitempty"`
FileContracts []FileContract `json:"fileContracts,omitempty"`
FileContractRevisions []FileContractRevision `json:"fileContractRevisions,omitempty"`
MinerFees []types.Currency `json:"minerFees,omitempty"`
ArbitraryData [][]byte `json:"arbitraryData,omitempty"`
Signatures []types.TransactionSignature `json:"signatures,omitempty"`
}

// A Block is a block containing wrapped transactions and siacoin
Expand Down
17 changes: 17 additions & 0 deletions persist/sqlite/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,21 @@ func addMinerFees(tx *txn, id int64, txn types.Transaction) error {
return nil
}

func addSignatures(tx *txn, id int64, txn types.Transaction) error {
stmt, err := tx.Prepare(`INSERT INTO transaction_signatures(transaction_id, transaction_order, parent_id, public_key_index, timelock, covered_fields, signature) VALUES (?, ?, ?, ?, ?, ?, ?)`)
if err != nil {
return fmt.Errorf("addMinerFees: failed to prepare statement: %w", err)
}
defer stmt.Close()

for i, sig := range txn.Signatures {
if _, err := stmt.Exec(id, i, encode(sig.ParentID), sig.PublicKeyIndex, sig.Timelock, encode(sig.CoveredFields), sig.Signature); err != nil {
return fmt.Errorf("addMinerFees: failed to execute statement: %w", err)
}
}
return nil
}

func addArbitraryData(tx *txn, id int64, txn types.Transaction) error {
stmt, err := tx.Prepare(`INSERT INTO transaction_arbitrary_data(transaction_id, transaction_order, data) VALUES (?, ?, ?)`)

Expand Down Expand Up @@ -281,6 +296,8 @@ func addTransactions(tx *txn, bid types.BlockID, txns []types.Transaction, scDBI
return fmt.Errorf("failed to add miner fees: %w", err)
} else if err := addArbitraryData(tx, txnID, txn); err != nil {
return fmt.Errorf("failed to add arbitrary data: %w", err)
} else if err := addSignatures(tx, txnID, txn); err != nil {
return fmt.Errorf("failed to add signatures: %w", err)
} else if err := addSiacoinInputs(tx, txnID, txn); err != nil {
return fmt.Errorf("failed to add siacoin inputs: %w", err)
} else if err := addSiacoinOutputs(tx, txnID, txn, scDBIds); err != nil {
Expand Down
13 changes: 13 additions & 0 deletions persist/sqlite/init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,19 @@ CREATE TABLE transaction_miner_fees (

CREATE INDEX transaction_miner_fees_transaction_id_index ON transaction_miner_fees(transaction_id);

CREATE TABLE transaction_signatures (
transaction_id INTEGER REFERENCES transactions(id) ON DELETE CASCADE NOT NULL,
transaction_order INTEGER NOT NULL,
parent_id BLOB NOT NULL,
public_key_index INTEGER NOT NULL,
timelock INTEGER NOT NULL,
covered_fields BLOB NOT NULL,
signature BLOB NOT NULL,
UNIQUE(transaction_id, transaction_order)
);

CREATE INDEX transaction_signatures_transaction_id_index ON transaction_signatures(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
30 changes: 30 additions & 0 deletions persist/sqlite/transactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,30 @@ ORDER BY transaction_order ASC`
return result, nil
}

// transactionSignatures returns the signatures for each transaction.
func transactionSignatures(tx *txn, txnIDs []int64) (map[int64][]types.TransactionSignature, error) {
query := `SELECT transaction_id, parent_id, public_key_index, timelock, covered_fields, signature
FROM transaction_signatures
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.TransactionSignature)
for rows.Next() {
var txnID int64
var sig types.TransactionSignature
if err := rows.Scan(&txnID, decode(&sig.ParentID), &sig.PublicKeyIndex, &sig.Timelock, decode(&sig.CoveredFields), &sig.Signature); err != nil {
return nil, fmt.Errorf("failed to scan signature: %w", err)
}
result[txnID] = append(result[txnID], sig)
}
return result, nil
}

// transactionSiacoinOutputs returns the siacoin outputs for each transaction.
func transactionSiacoinOutputs(tx *txn, txnIDs []int64) (map[int64][]explorer.SiacoinOutput, error) {
query := `SELECT ts.transaction_id, sc.output_id, sc.leaf_index, sc.source, sc.maturity_height, sc.address, sc.value
Expand Down Expand Up @@ -382,6 +406,11 @@ func (s *Store) getTransactions(tx *txn, dbIDs []int64) ([]explorer.Transaction,
return nil, fmt.Errorf("getTransactions: failed to get miner fees: %w", err)
}

txnSignatures, err := transactionSignatures(tx, dbIDs)
if err != nil {
return nil, fmt.Errorf("getTransactions: failed to get signatures: %w", err)
}

txnSiacoinInputs, err := transactionSiacoinInputs(tx, dbIDs)
if err != nil {
return nil, fmt.Errorf("getTransactions: failed to get siacoin inputs: %w", err)
Expand Down Expand Up @@ -426,6 +455,7 @@ func (s *Store) getTransactions(tx *txn, dbIDs []int64) ([]explorer.Transaction,
FileContractRevisions: txnFileContractRevisions[dbID],
MinerFees: txnMinerFees[dbID],
ArbitraryData: txnArbitraryData[dbID],
Signatures: txnSignatures[dbID],
}
results = append(results, txn)
}
Expand Down

0 comments on commit 07ab4cc

Please sign in to comment.