Browse Source

storage: store blocks and update current height within the same transaction

readme
George Tankersley 5 years ago
committed by George Tankersley
parent
commit
d53507cc39
  1. 34
      storage/sqlite3.go

34
storage/sqlite3.go

@ -123,39 +123,53 @@ func GetBlockRange(ctx context.Context, db *sql.DB, blockOut chan<- []byte, errO
func StoreBlock(conn *sql.DB, height int, hash string, sapling bool, encoded []byte) error { func StoreBlock(conn *sql.DB, height int, hash string, sapling bool, encoded []byte) error {
insertBlock := "INSERT INTO blocks (block_height, block_hash, sapling, compact_encoding) values (?, ?, ?, ?)" insertBlock := "INSERT INTO blocks (block_height, block_hash, sapling, compact_encoding) values (?, ?, ?, ?)"
_, err := conn.Exec(insertBlock, height, hash, sapling, encoded)
tx, err := conn.Begin()
if err != nil {
return errors.Wrap(err, fmt.Sprintf("creating db tx %d", height))
}
_, err = tx.Exec(insertBlock, height, hash, sapling, encoded)
if err != nil { if err != nil {
return errors.Wrap(err, fmt.Sprintf("storing compact block %d", height)) return errors.Wrap(err, fmt.Sprintf("storing compact block %d", height))
} }
currentHeight, err := GetCurrentHeight(context.Background(), conn) var currentHeight int
query := "SELECT current_height FROM state WHERE rowid = 1"
err = tx.QueryRow(query).Scan(&currentHeight)
if err != nil || height > currentHeight { if err != nil || height > currentHeight {
// TODO database transactions! err = setCurrentHeight(tx, height)
err = SetCurrentHeight(conn, height)
} }
return err
err = tx.Commit()
if err != nil {
return errors.Wrap(err, fmt.Sprintf("committing db tx %d", height))
}
return nil
} }
func SetCurrentHeight(conn *sql.DB, height int) error { func setCurrentHeight(tx *sql.Tx, height int) error {
update := "UPDATE state SET current_height=?, timestamp=CURRENT_TIMESTAMP WHERE rowid = 1" update := "UPDATE state SET current_height=?, timestamp=CURRENT_TIMESTAMP WHERE rowid = 1"
result, err := conn.Exec(update, height) result, err := tx.Exec(update, height)
if err != nil { if err != nil {
return errors.Wrap(err, "updating state row") return errors.Wrap(err, "updating state row")
} }
rowCount, err := result.RowsAffected() rowCount, err := result.RowsAffected()
if err != nil { if err != nil {
return errors.Wrap(err, "checking if state row exists") return errors.Wrap(err, "checking if state row exists after update")
} }
if rowCount == 0 { if rowCount == 0 {
// row does not yet exist // row does not yet exist
insert := "INSERT OR IGNORE INTO state (rowid, current_height) VALUES (1, ?)" insert := "INSERT OR IGNORE INTO state (rowid, current_height) VALUES (1, ?)"
result, err = conn.Exec(insert, height) result, err = tx.Exec(insert, height)
if err != nil { if err != nil {
return errors.Wrap(err, "on state row insert") return errors.Wrap(err, "on state row insert")
} }
rowCount, err = result.RowsAffected() rowCount, err = result.RowsAffected()
if err != nil { if err != nil {
return errors.Wrap(err, "checking if state row exists") return errors.Wrap(err, "checking if state row exists after insert")
} }
if rowCount != 1 { if rowCount != 1 {
return errors.New("totally failed to update current height state") return errors.New("totally failed to update current height state")

Loading…
Cancel
Save