From a7a9023bc1bcbfe8063a22436c7c1cdd15da42c8 Mon Sep 17 00:00:00 2001 From: "Owain G. Ainsworth" Date: Wed, 10 Jul 2013 00:11:02 +0100 Subject: [PATCH] Add ExistsTxSha to db interface. This function may be used to check for existance of a tx sha without having to fetch the data from the db. --- db.go | 4 ++++ sqlite3/operational_test.go | 10 ++++++++ sqlite3/sqlite.go | 4 ++++ sqlite3/sqlitetx.go | 48 +++++++++++++++++++++++++++++++++++-- test_coverage.txt | 26 ++++++++++---------- 5 files changed, 78 insertions(+), 14 deletions(-) diff --git a/db.go b/db.go index 2e1810465..7f2d04939 100644 --- a/db.go +++ b/db.go @@ -69,6 +69,10 @@ type Db interface { // more are present, use the special id `AllShas'. FetchHeightRange(startHeight, endHeight int64) (rshalist []btcwire.ShaHash, err error) + // ExistsTxSha returns whether or not the given tx hash is present in + // the database + ExistsTxSha(sha *btcwire.ShaHash) (exists bool) + // FetchTxAllBySha returns several pieces of data for a given // transaction hash. The implementation may cache the underlying data // if desired. diff --git a/sqlite3/operational_test.go b/sqlite3/operational_test.go index e91161c23..e731188d5 100644 --- a/sqlite3/operational_test.go +++ b/sqlite3/operational_test.go @@ -94,6 +94,11 @@ out: } origintxsha := &txin.PreviousOutpoint.Hash txneededList = append(txneededList, origintxsha) + + if !db.ExistsTxSha(origintxsha) { + t.Errorf("referenced tx not found %v ", origintxsha) + } + _, _, _, _, err := db.FetchTxAllBySha(origintxsha) if err != nil { t.Errorf("referenced tx not found %v err %v ", origintxsha, err) @@ -259,6 +264,11 @@ func testBackout(t *testing.T, mode int) { block := blocks[110] mblock := block.MsgBlock() txsha, err := mblock.Transactions[0].TxSha(block.ProtocolVersion()) + exists := db.ExistsTxSha(&txsha) + if exists { + t.Errorf("tx %v exists in db, failure expected") + } + _, _, _, err = db.FetchTxBySha(&txsha) _, err = db.FetchTxUsedBySha(&txsha) diff --git a/sqlite3/sqlite.go b/sqlite3/sqlite.go index 64e634db5..e41b71483 100644 --- a/sqlite3/sqlite.go +++ b/sqlite3/sqlite.go @@ -45,6 +45,8 @@ const ( txPragmaVacuumOn txPragmaVacuumOff txVacuum + txExistsShaStmt + txtmpExistsShaStmt ) var blkqueries []string = []string{ @@ -70,6 +72,8 @@ var txqueries []string = []string{ txPragmaVacuumOn: "PRAGMA auto_vacuum = FULL;", txPragmaVacuumOff: "PRAGMA auto_vacuum = NONE;", txVacuum: "VACUUM;", + txExistsShaStmt: "SELECT blockid FROM tx WHERE key = ?;", + txtmpExistsShaStmt: "SELECT blockid FROM txtmp WHERE key = ?;", } var log seelog.LoggerInterface = seelog.Disabled diff --git a/sqlite3/sqlitetx.go b/sqlite3/sqlitetx.go index 321d3a05e..1c05aa7e7 100644 --- a/sqlite3/sqlitetx.go +++ b/sqlite3/sqlitetx.go @@ -72,11 +72,55 @@ func (db *SqliteDb) insertTx(txsha *btcwire.ShaHash, blockidx int64, txoff int, return } -// FetchLocationBySha looks up the Tx sha information by name. -func (db *SqliteDb) FetchLocationBySha(txsha *btcwire.ShaHash) (blockidx int64, txoff int, txlen int, err error) { +// ExistsTxSha returns if the given tx sha exists in the database +func (db *SqliteDb) ExistsTxSha(txsha *btcwire.ShaHash) (exists bool) { db.dbLock.Lock() defer db.dbLock.Unlock() + if _, ok := db.fetchTxCache(txsha); ok { + return true + } + + return db.existsTxSha(txsha) +} + + +// existsTxSha returns if the given tx sha exists in the database.o +// Must be called with the db lock held. +func (db *SqliteDb) existsTxSha(txsha *btcwire.ShaHash) (exists bool) { + var blockid uint32 + + txop := db.txop(txExistsShaStmt) + row := txop.QueryRow(txsha.String()) + err := row.Scan(&blockid) + + if err == sql.ErrNoRows { + txop = db.txop(txtmpExistsShaStmt) + row = txop.QueryRow(txsha.String()) + err := row.Scan(&blockid) + + if err == sql.ErrNoRows { + return false + } + if err != nil { + log.Warnf("txTmpExistsTxSha: fail %v", err) + return false + } + log.Warnf("txtmpExistsTxSha: success") + return true + } + + if err != nil { + // ignore real errors? + log.Warnf("existsTxSha: fail %v", err) + return false + } + + return true +} + +// FetchLocationBySha looks up the Tx sha information by name. +func (db *SqliteDb) FetchLocationBySha(txsha *btcwire.ShaHash) (blockidx int64, txoff int, txlen int, err error) { return db.fetchLocationBySha(txsha) } diff --git a/test_coverage.txt b/test_coverage.txt index f1198084b..fb0a17c5f 100644 --- a/test_coverage.txt +++ b/test_coverage.txt @@ -3,34 +3,35 @@ github.com/conformal/btcdb/sqlite3/sqliteblock.go SqliteDb.NewestSha 100.00% github.com/conformal/btcdb/sqlite3/sqlite.go SqliteDb.endTx 100.00% (20/20) github.com/conformal/btcdb/sqlite3/sqlite.go SqliteDb.close 100.00% (9/9) github.com/conformal/btcdb/sqlite3/sqlite.go SqliteDb.txop 100.00% (7/7) -github.com/conformal/btcdb/sqlite3/sqlitedbcache.go SqliteDb.fetchTxCache 100.00% (7/7) github.com/conformal/btcdb/sqlite3/sqliteblock.go SqliteBlockIterator.Row 100.00% (7/7) +github.com/conformal/btcdb/sqlite3/sqlitedbcache.go SqliteDb.fetchTxCache 100.00% (7/7) github.com/conformal/btcdb/sqlite3/sqlitedbcache.go SqliteDb.FetchTxByShaList 100.00% (6/6) -github.com/conformal/btcdb/sqlite3/sqlitedbcache.go SqliteDb.InvalidateTxCache 100.00% (5/5) +github.com/conformal/btcdb/sqlite3/sqlitetx.go SqliteDb.ExistsTxSha 100.00% (5/5) github.com/conformal/btcdb/sqlite3/sqlitedbcache.go SqliteDb.InvalidateBlockCache 100.00% (5/5) -github.com/conformal/btcdb/sqlite3/sqlite.go SqliteDb.Sync 100.00% (3/3) -github.com/conformal/btcdb/sqlite3/sqlite.go SqliteDb.Close 100.00% (3/3) -github.com/conformal/btcdb/sqlite3/sqlitetx.go SqliteDb.FetchLocationBySha 100.00% (3/3) +github.com/conformal/btcdb/sqlite3/sqlitedbcache.go SqliteDb.InvalidateTxCache 100.00% (5/5) github.com/conformal/btcdb/sqlite3/sqliteblock.go SqliteDb.InsertBlockData 100.00% (3/3) +github.com/conformal/btcdb/sqlite3/sqlite.go SqliteDb.Close 100.00% (3/3) +github.com/conformal/btcdb/sqlite3/sqlite.go SqliteDb.Sync 100.00% (3/3) github.com/conformal/btcdb/sqlite3/sqlitetx.go SqliteDb.InsertTx 100.00% (3/3) -github.com/conformal/btcdb/sqlite3/sqlitedbcache.go SqliteDb.FetchTxBufBySha 100.00% (2/2) -github.com/conformal/btcdb/sqlite3/sqlitedbcache.go SqliteDb.InvalidateCache 100.00% (2/2) github.com/conformal/btcdb/sqlite3/sqliteblock.go SqliteBlockIterator.Close 100.00% (2/2) -github.com/conformal/btcdb/sqlite3/sqlitedbcache.go SqliteDb.FetchTxBySha 100.00% (2/2) -github.com/conformal/btcdb/sqlite3/sqlite.go OpenSqliteDB 100.00% (2/2) github.com/conformal/btcdb/sqlite3/sqlite.go CreateSqliteDB 100.00% (2/2) +github.com/conformal/btcdb/sqlite3/sqlite.go OpenSqliteDB 100.00% (2/2) +github.com/conformal/btcdb/sqlite3/sqlitedbcache.go SqliteDb.InvalidateCache 100.00% (2/2) +github.com/conformal/btcdb/sqlite3/sqlitedbcache.go SqliteDb.FetchTxBufBySha 100.00% (2/2) +github.com/conformal/btcdb/sqlite3/sqlitedbcache.go SqliteDb.FetchTxBySha 100.00% (2/2) github.com/conformal/btcdb/sqlite3/sqlite.go init 100.00% (1/1) +github.com/conformal/btcdb/sqlite3/sqlitetx.go SqliteDb.FetchLocationBySha 100.00% (1/1) github.com/conformal/btcdb/sqlite3/sqliteblock.go SqliteBlockIterator.NextRow 100.00% (1/1) github.com/conformal/btcdb/sqlite3/sqlitetx.go SqliteDb.insertTx 96.77% (30/31) github.com/conformal/btcdb/sqlite3/sqlitedbcache.go SqliteDb.insertBlockCache 92.31% (12/13) +github.com/conformal/btcdb/sqlite3/sqliteblock.go SqliteDb.FetchBlockShaByHeight 91.67% (11/12) github.com/conformal/btcdb/sqlite3/sqlitedbcache.go SqliteDb.insertTxCache 91.67% (11/12) -github.com/conformal/btcdb/sqlite3/sqliteblock.go SqliteDb.FetchBlockShaByIdx 91.67% (11/12) github.com/conformal/btcdb/sqlite3/sqlite.go SqliteDb.rePlayTransaction 90.00% (18/20) github.com/conformal/btcdb/sqlite3/sqliteblock.go SqliteDb.NewIterateBlocks 88.24% (15/17) github.com/conformal/btcdb/sqlite3/sqlite.go SqliteDb.RollbackClose 87.50% (7/8) github.com/conformal/btcdb/sqlite3/sqliteblock.go SqliteDb.fetchSha 85.71% (12/14) github.com/conformal/btcdb/sqlite3/sqliteblock.go SqliteDb.ExistsSha 85.71% (6/7) -github.com/conformal/btcdb/sqlite3/sqliteblock.go SqliteDb.FetchIdxRange 84.62% (22/26) +github.com/conformal/btcdb/sqlite3/sqliteblock.go SqliteDb.FetchHeightRange 84.62% (22/26) github.com/conformal/btcdb/sqlite3/sqliteblock.go SqliteDb.insertBlockData 84.00% (21/25) github.com/conformal/btcdb/sqlite3/sqlitetx.go SqliteDb.fetchLocationBySha 84.00% (21/25) github.com/conformal/btcdb/sqlite3/sqlitedbcache.go SqliteDb.FetchBlockBySha 83.33% (10/12) @@ -38,6 +39,7 @@ github.com/conformal/btcdb/sqlite3/sqlitedbcache.go SqliteDb.fetchBlockCache 8 github.com/conformal/btcdb/sqlite3/sqlitetx.go SqliteDb.FetchTxUsedBySha 82.61% (19/23) github.com/conformal/btcdb/sqlite3/sqliteblock.go insertGenesisBlock 81.82% (9/11) github.com/conformal/btcdb/sqlite3/sqlite.go newOrCreateSqliteDB 79.25% (42/53) +github.com/conformal/btcdb/sqlite3/sqlitetx.go SqliteDb.existsTxSha 78.95% (15/19) github.com/conformal/btcdb/sqlite3/sqlite.go SqliteDb.startTx 78.57% (11/14) github.com/conformal/btcdb/sqlite3/sqliteblock.go SqliteDb.blkExistsSha 77.78% (7/9) github.com/conformal/btcdb/sqlite3/sqlitedbcache.go SqliteDb.FetchTxAllBySha 77.14% (27/35) @@ -47,5 +49,5 @@ github.com/conformal/btcdb/sqlite3/sqlite.go SqliteDb.syncPoint 71.43% (5/7) github.com/conformal/btcdb/sqlite3/sqlite.go createDB 70.59% (12/17) github.com/conformal/btcdb/sqlite3/sqlite.go SqliteDb.DropAfterBlockBySha 68.57% (24/35) github.com/conformal/btcdb/sqlite3/sqlite.go SqliteDb.InsertBlock 46.00% (23/50) -github.com/conformal/btcdb/sqlite3 ----------------------------- 82.15% (566/689) +github.com/conformal/btcdb/sqlite3 ------------------------------ 82.14% (584/711)