Exemple #1
0
// 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
}
Exemple #2
0
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
}
Exemple #3
0
// 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
}
Exemple #4
0
// 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
}
Exemple #5
0
// 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
}
Exemple #6
0
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
}
Exemple #7
0
// 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
}
Exemple #8
0
// 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
}