Exemplo n.º 1
0
func (db *unspentDb) del(idx *btc.TxPrevOut) {
	if db.ch.CB.NotifyTx != nil {
		db.ch.CB.NotifyTx(idx, nil)
	}
	key := qdb.KeyType(idx.UIdx())
	db.dbN(int(idx.Hash[31]) % NumberOfUnspentSubDBs).Del(key)
}
Exemplo n.º 2
0
func (db *unspentDb) add(idx *btc.TxPrevOut, Val_Pk *btc.TxOut) {
	v := make([]byte, SCR_OFFS+len(Val_Pk.Pk_script))
	copy(v[0:32], idx.Hash[:])
	binary.LittleEndian.PutUint32(v[32:36], idx.Vout)
	binary.LittleEndian.PutUint64(v[36:44], Val_Pk.Value)
	binary.LittleEndian.PutUint32(v[44:48], Val_Pk.BlockHeight)
	copy(v[SCR_OFFS:], Val_Pk.Pk_script)
	k := qdb.KeyType(idx.UIdx())
	var flgz uint32
	dbN := db.dbN(int(idx.Hash[31]) % NumberOfUnspentSubDBs)
	if stealthIndex(v) {
		if db.ch.CB.NotifyStealthTx != nil {
			db.ch.CB.NotifyStealthTx(dbN, k, NewWalkRecord(v))
		}
		flgz = qdb.YES_CACHE | qdb.YES_BROWSE
	} else {
		if db.ch.CB.NotifyTx != nil {
			db.ch.CB.NotifyTx(idx, Val_Pk)
		}
		if Val_Pk.Value < MinBrowsableOutValue {
			flgz = qdb.NO_CACHE | qdb.NO_BROWSE
		} else if NocacheBlocksBelow == -1 {
			flgz = qdb.NO_CACHE | qdb.NO_BROWSE
		}
	}
	dbN.PutExt(k, v, flgz)
}
Exemplo n.º 3
0
// Return txs in mempool that are spending any outputs form the given tx
func findPendingTxs(tx *btc.Tx) (res []BIDX) {
	var in btc.TxPrevOut
	copy(in.Hash[:], tx.Hash.Hash[:])
	for in.Vout = 0; in.Vout < uint32(len(tx.TxOut)); in.Vout++ {
		if r, ok := SpentOutputs[in.UIdx()]; ok {
			res = append(res, r)
		}
	}
	return res
}
Exemplo n.º 4
0
// This is called while accepting the block (from the chain's thread)
func TxNotify(idx *btc.TxPrevOut, valpk *btc.TxOut) {
	var update_wallet bool

	BalanceMutex.Lock()

	if valpk != nil {
		// Extract hash160 from pkscript
		adr := btc.NewAddrFromPkScript(valpk.Pk_script, common.Testnet)
		if adr != nil {
			if rec, ok := CachedAddrs[adr.Hash160]; ok {
				rec.Value += valpk.Value
				utxo := new(chain.OneUnspentTx)
				utxo.TxPrevOut = *idx
				utxo.Value = valpk.Value
				utxo.MinedAt = valpk.BlockHeight
				utxo.BtcAddr = CacheUnspent[rec.CacheIndex].BtcAddr
				CacheUnspent[rec.CacheIndex].AllUnspentTx = append(CacheUnspent[rec.CacheIndex].AllUnspentTx, utxo)
				CacheUnspentIdx[idx.UIdx()] = &OneCachedUnspentIdx{Index: rec.CacheIndex, Record: utxo}
				if rec.InWallet {
					update_wallet = true
				}
			}
		}
	} else {
		ii := idx.UIdx()
		if ab, present := CacheUnspentIdx[ii]; present {
			adrec := CacheUnspent[ab.Index]
			//println("removing", idx.String())
			rec := CachedAddrs[adrec.BtcAddr.Hash160]
			if rec == nil {
				panic("rec not found for " + adrec.BtcAddr.String())
			}
			rec.Value -= ab.Record.Value
			if rec.InWallet {
				update_wallet = true
			}
			for j := range adrec.AllUnspentTx {
				if adrec.AllUnspentTx[j] == ab.Record {
					//println("found it at index", j)
					adrec.AllUnspentTx = append(adrec.AllUnspentTx[:j], adrec.AllUnspentTx[j+1:]...)
					break
				}
			}
			delete(CacheUnspentIdx, ii)
		}
	}

	if update_wallet {
		sync_wallet()
	}
	BalanceMutex.Unlock()
}
Exemplo n.º 5
0
func (db *unspentDb) get(po *btc.TxPrevOut) (res *btc.TxOut, e error) {
	ind := qdb.KeyType(po.UIdx())
	val := db.dbN(int(po.Hash[31]) % NumberOfUnspentSubDBs).Get(ind)
	if val == nil {
		e = errors.New("Unspent not found")
		return
	}

	if len(val) < SCR_OFFS {
		panic(fmt.Sprint("unspent record too short:", len(val)))
	}

	res = new(btc.TxOut)
	res.Value = binary.LittleEndian.Uint64(val[36:44])
	res.BlockHeight = binary.LittleEndian.Uint32(val[44:48])
	res.Pk_script = make([]byte, len(val)-SCR_OFFS)
	copy(res.Pk_script, val[SCR_OFFS:])
	return
}
Exemplo n.º 6
0
// This is called while accepting the block (from the chain's thread)
func TxNotifyDel(txid []byte, outs []bool) {
	var update_wallet bool
	BalanceMutex.Lock()

	var uidx btc.TxPrevOut
	copy(uidx.Hash[:], txid)
	for uidx.Vout = 0; uidx.Vout < uint32(len(outs)); uidx.Vout++ {
		if outs[uidx.Vout] {
			ii := uidx.UIdx()
			if ab, present := CacheUnspentIdx[ii]; present {
				adrec := CacheUnspent[ab.Index]
				rec := CachedAddrs[adrec.BtcAddr.Hash160]
				if rec == nil {
					panic("rec not found for " + adrec.BtcAddr.String())
				}
				rec.Value -= ab.Record.Value
				if rec.InWallet {
					update_wallet = true
				}
				for j := range adrec.AllUnspentTx {
					if adrec.AllUnspentTx[j] == ab.Record {
						//println("found it at index", j)
						adrec.AllUnspentTx = append(adrec.AllUnspentTx[:j], adrec.AllUnspentTx[j+1:]...)
						break
					}
				}
				delete(CacheUnspentIdx, ii)
			}
		}
	}

	if update_wallet {
		sync_wallet()
	}
	BalanceMutex.Unlock()
}