Exemple #1
0
// ShaHashToBig converts a btcwire.ShaHash into a big.Int that can be used to
// perform math comparisons.
func ShaHashToBig(hash *btcwire.ShaHash) *big.Int {
	// A ShaHash is in little-endian, but the big package wants the bytes
	// in big-endian.  Reverse them.  ShaHash.Bytes makes a copy, so it
	// is safe to modify the returned buffer.
	buf := hash.Bytes()
	blen := len(buf)
	for i := 0; i < blen/2; i++ {
		buf[i], buf[blen-1-i] = buf[blen-1-i], buf[i]
	}

	return new(big.Int).SetBytes(buf)
}
Exemple #2
0
// HashMerkleBranches takes two hashes, treated as the left and right tree
// nodes, and returns the hash of their concatenation.  This is a helper
// function used to aid in the generation of a merkle tree.
func HashMerkleBranches(left *btcwire.ShaHash, right *btcwire.ShaHash) *btcwire.ShaHash {
	// Concatenate the left and right nodes.
	var sha [btcwire.HashSize * 2]byte
	copy(sha[:btcwire.HashSize], left.Bytes())
	copy(sha[btcwire.HashSize:], right.Bytes())

	// Create a new sha hash from the double sha 256.  Ignore the error
	// here since SetBytes can't fail here due to the fact DoubleSha256
	// always returns a []byte of the right size regardless of input.
	newSha, _ := btcwire.NewShaHash(btcwire.DoubleSha256(sha[:]))
	return newSha
}
Exemple #3
0
func (db *LevelDb) setBlk(sha *btcwire.ShaHash, blkHeight int64, buf []byte) {
	// serialize
	var lw [8]byte
	binary.LittleEndian.PutUint64(lw[0:8], uint64(blkHeight))

	shaKey := shaBlkToKey(sha)
	blkKey := int64ToKey(blkHeight)

	shaB := sha.Bytes()
	blkVal := make([]byte, len(shaB)+len(buf))
	copy(blkVal[0:], shaB)
	copy(blkVal[len(shaB):], buf)

	db.lBatch().Put(shaKey, lw[:])
	db.lBatch().Put(blkKey, blkVal)
}
Exemple #4
0
// UpdateAddrIndexForBlock updates the stored addrindex with passed
// index information for a particular block height. Additionally, it
// will update the stored meta-data related to the curent tip of the
// addr index. These two operations are performed in an atomic
// transaction which is commited before the function returns.
// Transactions indexed by address are stored with the following format:
//   * prefix || hash160 || blockHeight || txoffset || txlen
// Indexes are stored purely in the key, with blank data for the actual value
// in order to facilitate ease of iteration by their shared prefix and
// also to allow limiting the number of returned transactions (RPC).
// Alternatively, indexes for each address could be stored as an
// append-only list for the stored value. However, this add unnecessary
// overhead when storing and retrieving since the entire list must
// be fetched each time.
func (db *LevelDb) UpdateAddrIndexForBlock(blkSha *btcwire.ShaHash, blkHeight int64, addrIndex database.BlockAddrIndex) error {
	db.dbLock.Lock()
	defer db.dbLock.Unlock()

	var blankData []byte
	batch := db.lBatch()
	defer db.lbatch.Reset()

	// Write all data for the new address indexes in a single batch
	// transaction.
	for addrKey, indexes := range addrIndex {
		for _, txLoc := range indexes {
			index := &txAddrIndex{
				hash160:   addrKey,
				blkHeight: blkHeight,
				txoffset:  txLoc.TxStart,
				txlen:     txLoc.TxLen,
			}
			// The index is stored purely in the key.
			packedIndex := addrIndexToKey(index)
			batch.Put(packedIndex, blankData)
		}
	}

	// Update tip of addrindex.
	newIndexTip := make([]byte, 40, 40)
	copy(newIndexTip[:32], blkSha.Bytes())
	binary.LittleEndian.PutUint64(newIndexTip[32:], uint64(blkHeight))
	batch.Put(addrIndexMetaDataKey, newIndexTip)

	if err := db.lDb.Write(batch, db.wo); err != nil {
		return err
	}

	db.lastAddrIndexBlkIdx = blkHeight
	db.lastAddrIndexBlkSha = *blkSha

	return nil
}
Exemple #5
0
func shaSpentTxToKey(sha *btcwire.ShaHash) []byte {
	shaB := sha.Bytes()
	shaB = append(shaB, "sx"...)
	return shaB
}
Exemple #6
0
func shaBlkToKey(sha *btcwire.ShaHash) []byte {
	shaB := sha.Bytes()
	return shaB
}