deals with incoming blocks and txs

gets stuck on reorgs though, until program is restarted
This commit is contained in:
Tadge Dryja 2016-01-22 17:15:56 -08:00
parent 5a7c04bdb5
commit 851d3533e5
2 changed files with 44 additions and 21 deletions

@ -19,7 +19,7 @@ import (
type TxStore struct {
OKTxids map[wire.ShaHash]int32 // known good txids and their heights
Utxos []Utxo // stacks on stacks
Utxos []*Utxo // stacks on stacks
Sum int64 // racks on racks
Adrs []MyAdr // endeavouring to acquire capital
LastIdx uint32 // should equal len(Adrs)
@ -118,16 +118,40 @@ func (t *TxStore) AbsorbTx(tx *wire.MsgTx, height int32) error {
if tx == nil {
return fmt.Errorf("Tried to add nil tx")
}
var hits uint32
var acq int64
newTxid := tx.TxSha()
var hits uint32 // how many outputs of this tx are ours
var acq int64 // total acquirement from this tx
// check if any of the tx's outputs match my adrs
for i, out := range tx.TxOut { // in each output of tx
dup := false // start by assuming its new until found duplicate
newOp := wire.NewOutPoint(&newTxid, uint32(i))
// first look for dupes -- already known outpoints.
// if we find a dupe here overwrite it to the DB.
for _, u := range t.Utxos {
dup = OutPointsEqual(*newOp, u.Op) // is this outpoint known?
if dup { // found dupe
fmt.Printf(" %s is dupe\t", newOp.String())
u.AtHeight = height // ONLY difference is height
// save modified utxo to db, overwriting old one
err := u.SaveToDB(t.StateDB)
if err != nil {
return err
}
break // out of the t.Utxo range loop
}
}
if dup {
// if we found the outpoint to be a dup above, don't add it again
// when it matches an address, just go to the next outpoint
continue
}
for _, a := range t.Adrs { // compare to each adr we have
// check for full script to eliminate false positives
aPKscript, err := txscript.PayToAddrScript(a.PkhAdr)
if err != nil {
return err
}
// already checked for dupes, this must be a new outpoint
if bytes.Equal(out.PkScript, aPKscript) { // hit
var newu Utxo
@ -139,17 +163,14 @@ func (t *TxStore) AbsorbTx(tx *wire.MsgTx, height int32) error {
newop.Hash = tx.TxSha()
newop.Index = uint32(i)
newu.Op = newop
dupe, err := newu.SaveToDB(t.StateDB)
err = newu.SaveToDB(t.StateDB)
if err != nil {
return err
}
if !dupe { // only save to DB if new txid
t.Utxos = append(t.Utxos, newu)
acq += out.Value
hits++
} else {
fmt.Printf("...dupe ")
}
acq += out.Value
hits++
t.Utxos = append(t.Utxos, &newu) // always add new utxo
break
}
}

@ -100,26 +100,28 @@ func (ts *TxStore) PopulateAdrs(lastKey uint32) error {
return nil
}
// SaveToDB write a utxo to disk, and returns true if it's a dupe
func (u *Utxo) SaveToDB(dbx *bolt.DB) (bool, error) {
var dupe bool
// SaveToDB write a utxo to disk, overwriting an old utxo of the same outpoint
func (u *Utxo) SaveToDB(dbx *bolt.DB) error {
err := dbx.Update(func(tx *bolt.Tx) error {
duf := tx.Bucket(BKTUtxos)
b, err := u.ToBytes()
if err != nil {
return err
}
if duf.Get(b[:36]) != nil { // already have tx
dupe = true
return nil
}
// don't check for dupes here, check in AbsorbTx(). here overwrite.
// if duf.Get(b[:36]) != nil { // already have tx
// dupe = true
// return nil
// }
// key : val is txid:everything else
return duf.Put(b[:36], b[36:])
})
if err != nil {
return false, err
return err
}
return dupe, nil
return nil
}
func (ts *TxStore) MarkSpent(op *wire.OutPoint, h int32, stx *wire.MsgTx) error {
@ -196,7 +198,7 @@ func (ts *TxStore) LoadFromDB() error {
return err
}
// and add it to ram
ts.Utxos = append(ts.Utxos, newU)
ts.Utxos = append(ts.Utxos, &newU)
ts.Sum += newU.Value
} else {
fmt.Printf("had utxo %x but spent by tx %x...\n",