Skip to content

Commit

Permalink
explicitly delete from last_contract_revision in cleanupUnusedFileCon…
Browse files Browse the repository at this point in the history
…tracts and add more contracts checks throughout
  • Loading branch information
chris124567 committed Sep 18, 2024
1 parent 7818dde commit 0b7f683
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 19 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module go.sia.tech/explored

go 1.22
go 1.22.0

toolchain go1.23.0

Expand Down
27 changes: 18 additions & 9 deletions persist/sqlite/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -735,8 +735,8 @@ func updateFileContractElements(tx *txn, revert bool, b types.Block, fces []expl
}
defer stmt.Close()

revisionStmt, err := tx.Prepare(`INSERT INTO last_contract_revision(contract_id, block_id, contract_element_id, ed25519_renter_key, ed25519_host_key)
VALUES (?, ?, ?, ?, ?)
revisionStmt, err := tx.Prepare(`INSERT INTO last_contract_revision(contract_id, contract_element_id, ed25519_renter_key, ed25519_host_key)
VALUES (?, ?, ?, ?)
ON CONFLICT (contract_id)
DO UPDATE SET contract_element_id = ?, ed25519_renter_key = COALESCE(?, ed25519_renter_key), ed25519_host_key = COALESCE(?, ed25519_host_key)`)
if err != nil {
Expand Down Expand Up @@ -815,7 +815,7 @@ func updateFileContractElements(tx *txn, revert bool, b types.Block, fces []expl
hostKey = encode(keys[1]).([]byte)
}

if _, err := revisionStmt.Exec(encode(fcID), encode(b.ID()), dbID, renterKey, hostKey, dbID, renterKey, hostKey); err != nil {
if _, err := revisionStmt.Exec(encode(fcID), dbID, renterKey, hostKey, dbID, renterKey, hostKey); err != nil {
return fmt.Errorf("failed to update last revision number: %w", err)
}
}
Expand Down Expand Up @@ -913,23 +913,32 @@ func addMetrics(tx *txn, s explorer.UpdateState) error {
}

func cleanupUnusedFileContracts(tx *txn, fces []explorer.FileContractUpdate) error {
deleteStmt, err := tx.Prepare(`DELETE FROM file_contract_elements WHERE contract_id = ? AND revision_number = ?`)
deleteFCEStmt, err := tx.Prepare(`DELETE FROM file_contract_elements WHERE contract_id = ? AND revision_number = ?`)
if err != nil {
return fmt.Errorf("updateFileContractElements: failed to prepare delete file_contract_elements statement: %w", err)
}
defer deleteFCEStmt.Close()

deleteRevisionStmt, err := tx.Prepare(`DELETE FROM last_contract_revision WHERE contract_id = ?`)
if err != nil {
return fmt.Errorf("updateFileContractElements: failed to prepare last_contract_revision statement: %w", err)
return fmt.Errorf("updateFileContractElements: failed to prepare delete last_contract_revision statement: %w", err)
}
defer deleteStmt.Close()
defer deleteRevisionStmt.Close()

for _, update := range fces {
// Reverting
if update.Revision != nil {
// Delete the revision
if _, err := deleteStmt.Exec(encode(update.Revision.ID), encode(update.Revision.FileContract.RevisionNumber)); err != nil {
if _, err := deleteFCEStmt.Exec(encode(update.Revision.ID), encode(update.Revision.FileContract.RevisionNumber)); err != nil {
return fmt.Errorf("updateFileContractElements: failed to remove reverted revision: %w", err)
}
} else {
// Delete the original contract
if _, err := deleteStmt.Exec(encode(update.FileContractElement.ID), encode(update.FileContractElement.FileContract.RevisionNumber)); err != nil {
return fmt.Errorf("updateFileContractElements: failed to remove reverted revision: %w", err)
if _, err := deleteRevisionStmt.Exec(encode(update.FileContractElement.ID)); err != nil {
return fmt.Errorf("updateFileContractElements: failed to remove reverted original from last_contract_revision: %w", err)
}
if _, err := deleteFCEStmt.Exec(encode(update.FileContractElement.ID), encode(update.FileContractElement.FileContract.RevisionNumber)); err != nil {
return fmt.Errorf("updateFileContractElements: failed to remove reverted original from file_contract_elements: %w", err)
}
}
}
Expand Down
51 changes: 43 additions & 8 deletions persist/sqlite/consensus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2666,6 +2666,21 @@ func TestMultipleReorgFileContract(t *testing.T) {
checkFCRevisions(t, []uint64{0, 1}, dbFCs)
}

{
renterContracts, err := db.ContractsKey(renterPublicKey)
if err != nil {
t.Fatal(err)
}
hostContracts, err := db.ContractsKey(hostPublicKey)
if err != nil {
t.Fatal(err)
}
check(t, "renter contracts and host contracts", len(renterContracts), len(hostContracts))
check(t, "len(contracts)", 1, len(renterContracts))
checkFC(false, false, revFC, renterContracts[0])
checkFC(false, false, revFC, hostContracts[0])
}

{
txns, err := db.Transactions([]types.TransactionID{reviseTxn.ID()})
if err != nil {
Expand Down Expand Up @@ -2748,14 +2763,6 @@ func TestMultipleReorgFileContract(t *testing.T) {
syncDB(t, db, cm)
}

{
dbFCs, err := db.ContractRevisions(fcID)
if err != nil {
t.Fatal(err)
}
checkFCRevisions(t, []uint64{0, 1}, dbFCs)
}

// revision should be applied
{
dbFCs, err := db.Contracts([]types.FileContractID{fcID})
Expand All @@ -2774,6 +2781,21 @@ func TestMultipleReorgFileContract(t *testing.T) {
checkFCRevisions(t, []uint64{0, 1}, dbFCs)
}

{
renterContracts, err := db.ContractsKey(renterPublicKey)
if err != nil {
t.Fatal(err)
}
hostContracts, err := db.ContractsKey(hostPublicKey)
if err != nil {
t.Fatal(err)
}
check(t, "renter contracts and host contracts", len(renterContracts), len(hostContracts))
check(t, "len(contracts)", 1, len(renterContracts))
checkFC(false, false, revFC, renterContracts[0])
checkFC(false, false, revFC, hostContracts[0])
}

// should have revision filesize
checkMetrics(t, db, cm, explorer.Metrics{
TotalHosts: 0,
Expand Down Expand Up @@ -2810,6 +2832,19 @@ func TestMultipleReorgFileContract(t *testing.T) {
check(t, "fcs", 0, len(dbFCs))
}

{
renterContracts, err := db.ContractsKey(renterPublicKey)
if err != nil {
t.Fatal(err)
}
hostContracts, err := db.ContractsKey(hostPublicKey)
if err != nil {
t.Fatal(err)
}
check(t, "renter contracts and host contracts", len(renterContracts), len(hostContracts))
check(t, "len(contracts)", 0, len(renterContracts))
}

{
dbFCs, err := db.ContractRevisions(fcID)
if err != nil {
Expand Down
1 change: 0 additions & 1 deletion persist/sqlite/init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ CREATE INDEX file_contract_elements_contract_id_index ON file_contract_elements(

CREATE TABLE last_contract_revision (
contract_id BLOB PRIMARY KEY NOT NULL,
block_id BLOB REFERENCES blocks(id) ON DELETE CASCADE NOT NULL,
ed25519_renter_key BLOB,
ed25519_host_key BLOB,
contract_element_id INTEGER UNIQUE REFERENCES file_contract_elements(id) NOT NULL
Expand Down

0 comments on commit 0b7f683

Please sign in to comment.