// FetchHeightRange looks up a range of blocks by the start and ending // heights. Fetch is inclusive of the start height and exclusive of the // ending height. To fetch all hashes from the start height until no // more are present, use the special id `AllShas'. func (db *LevelDb) FetchHeightRange(startHeight, endHeight int64) (rshalist []btcwire.ShaHash, err error) { db.dbLock.Lock() defer db.dbLock.Unlock() var endidx int64 if endHeight == btcdb.AllShas { endidx = startHeight + 500 } else { endidx = endHeight } shalist := make([]btcwire.ShaHash, 0, endidx-startHeight) for height := startHeight; height < endidx; height++ { // TODO(drahn) fix blkFile from height key := int64ToKey(height) blkVal, lerr := db.lDb.Get(key, db.ro) if lerr != nil { break } var sha btcwire.ShaHash sha.SetBytes(blkVal[0:32]) shalist = append(shalist, sha) } if err != nil { return } //log.Tracef("FetchIdxRange idx %v %v returned %v shas err %v", startHeight, endHeight, len(shalist), err) return shalist, nil }
func parsesha(argstr string) (argtype int, height int64, psha *btcwire.ShaHash, err error) { var sha btcwire.ShaHash var hashbuf string switch len(argstr) { case 64: hashbuf = argstr case 66: if argstr[0:2] != "0x" { log.Infof("prefix is %v", argstr[0:2]) err = ErrBadShaPrefix return } hashbuf = argstr[2:] default: if len(argstr) <= 16 { // assume value is height argtype = ArgHeight var h int h, err = strconv.Atoi(argstr) if err == nil { height = int64(h) return } log.Infof("Unable to parse height %v, err %v", height, err) } err = ErrBadShaLen return } var buf [32]byte for idx, ch := range hashbuf { var val rune switch { case ch >= '0' && ch <= '9': val = ch - '0' case ch >= 'a' && ch <= 'f': val = ch - 'a' + rune(10) case ch >= 'A' && ch <= 'F': val = ch - 'A' + rune(10) default: err = ErrBadShaChar return } b := buf[31-idx/2] if idx&1 == 1 { b |= byte(val) } else { b |= (byte(val) << 4) } buf[31-idx/2] = b } sha.SetBytes(buf[0:32]) psha = &sha return }
// Row returns row data for block iterator. func (bi *SqliteBlockIterator) Row() (key *btcwire.ShaHash, pver uint32, buf []byte, err error) { var keybytes []byte err = bi.rows.Scan(&keybytes, &pver, &buf) if err == nil { var retkey btcwire.ShaHash retkey.SetBytes(keybytes) key = &retkey } return }
// fetchBlockShaByHeight returns a block hash based on its height in the // block chain. func (db *LevelDb) fetchBlockShaByHeight(height int64) (rsha *btcwire.ShaHash, err error) { key := int64ToKey(height) blkVal, err := db.lDb.Get(key, db.ro) if err != nil { log.Tracef("failed to find height %v", height) return // exists ??? } var sha btcwire.ShaHash sha.SetBytes(blkVal[0:32]) return &sha, nil }
// FetchBlockShaByHeight returns a block hash based on its height in the // block chain. func (db *SqliteDb) FetchBlockShaByHeight(height int64) (sha *btcwire.ShaHash, err error) { var row *sql.Row db.dbLock.Lock() defer db.dbLock.Unlock() blockidx := height + 1 // skew between btc blockid and sql row = db.blkStmts[blkFetchIdx].QueryRow(blockidx) var shabytes []byte err = row.Scan(&shabytes) if err != nil { return } var shaval btcwire.ShaHash shaval.SetBytes(shabytes) return &shaval, nil }
func (db *LevelDb) getBlkByHeight(blkHeight int64) (rsha *btcwire.ShaHash, rbuf []byte, err error) { var blkVal []byte key := int64ToKey(blkHeight) blkVal, err = db.lDb.Get(key, db.ro) if err != nil { log.Tracef("failed to find height %v", blkHeight) return // exists ??? } var sha btcwire.ShaHash sha.SetBytes(blkVal[0:32]) blockdata := make([]byte, len(blkVal[32:])) copy(blockdata[:], blkVal[32:]) return &sha, blockdata, nil }
// NewestSha provides an interface to quickly look up the sha of // the most recent (end) of the block chain. func (db *SqliteDb) NewestSha() (sha *btcwire.ShaHash, blkid int64, err error) { var row *sql.Row var blockidx int64 db.dbLock.Lock() defer db.dbLock.Unlock() // answer may be cached if db.lastBlkShaCached == true { shacopy := db.lastBlkSha sha = &shacopy blkid = db.lastBlkIdx - 1 // skew between btc blockid and sql return } querystr := "SELECT key, blockid FROM block ORDER BY blockid DESC;" tx := &db.txState if tx.tx != nil { row = tx.tx.QueryRow(querystr) } else { row = db.sqldb.QueryRow(querystr) } var shabytes []byte err = row.Scan(&shabytes, &blockidx) if err == nil { var retsha btcwire.ShaHash retsha.SetBytes(shabytes) sha = &retsha blkid = blockidx - 1 // skew between btc blockid and sql db.lastBlkSha = retsha db.lastBlkIdx = blockidx db.lastBlkShaCached = true } return }
// FetchHeightRange looks up a range of blocks by the start and ending // heights. Fetch is inclusive of the start height and exclusive of the // ending height. To fetch all hashes from the start height until no // more are present, use the special id `AllShas'. func (db *SqliteDb) FetchHeightRange(startHeight, endHeight int64) (rshalist []btcwire.ShaHash, err error) { db.dbLock.Lock() defer db.dbLock.Unlock() startidx := startHeight + 1 // skew between btc block height and sql var endidx int64 if endHeight == btcdb.AllShas { endidx = btcdb.AllShas // no skew if asking for all } else { endidx = endHeight + 1 // skew between btc block height and sql } rows, err := db.blkStmts[blkFetchIdxList].Query(startidx, endidx) if err != nil { log.Warnf("query failed %v", err) return } var shalist []btcwire.ShaHash for rows.Next() { var sha btcwire.ShaHash var shabytes []byte err = rows.Scan(&shabytes) if err != nil { log.Warnf("wtf? %v", err) break } sha.SetBytes(shabytes) shalist = append(shalist, sha) } rows.Close() if err == nil { rshalist = shalist } log.Tracef("FetchIdxRange idx %v %v returned %v shas err %v", startHeight, endHeight, len(shalist), err) return }