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

View File

@ -19,7 +19,7 @@ import (
type TxStore struct { type TxStore struct {
OKTxids map[wire.ShaHash]int32 // known good txids and their heights 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 Sum int64 // racks on racks
Adrs []MyAdr // endeavouring to acquire capital Adrs []MyAdr // endeavouring to acquire capital
LastIdx uint32 // should equal len(Adrs) LastIdx uint32 // should equal len(Adrs)
@ -118,16 +118,40 @@ func (t *TxStore) AbsorbTx(tx *wire.MsgTx, height int32) error {
if tx == nil { if tx == nil {
return fmt.Errorf("Tried to add nil tx") return fmt.Errorf("Tried to add nil tx")
} }
var hits uint32 newTxid := tx.TxSha()
var acq int64 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 // check if any of the tx's outputs match my adrs
for i, out := range tx.TxOut { // in each output of tx 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 for _, a := range t.Adrs { // compare to each adr we have
// check for full script to eliminate false positives // check for full script to eliminate false positives
aPKscript, err := txscript.PayToAddrScript(a.PkhAdr) aPKscript, err := txscript.PayToAddrScript(a.PkhAdr)
if err != nil { if err != nil {
return err return err
} }
// already checked for dupes, this must be a new outpoint
if bytes.Equal(out.PkScript, aPKscript) { // hit if bytes.Equal(out.PkScript, aPKscript) { // hit
var newu Utxo var newu Utxo
@ -139,17 +163,14 @@ func (t *TxStore) AbsorbTx(tx *wire.MsgTx, height int32) error {
newop.Hash = tx.TxSha() newop.Hash = tx.TxSha()
newop.Index = uint32(i) newop.Index = uint32(i)
newu.Op = newop newu.Op = newop
dupe, err := newu.SaveToDB(t.StateDB) err = newu.SaveToDB(t.StateDB)
if err != nil { if err != nil {
return err return err
} }
if !dupe { // only save to DB if new txid
t.Utxos = append(t.Utxos, newu) acq += out.Value
acq += out.Value hits++
hits++ t.Utxos = append(t.Utxos, &newu) // always add new utxo
} else {
fmt.Printf("...dupe ")
}
break break
} }
} }

View File

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