deals with incoming blocks and txs
gets stuck on reorgs though, until program is restarted
This commit is contained in:
parent
5a7c04bdb5
commit
851d3533e5
@ -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++
|
||||||
} else {
|
t.Utxos = append(t.Utxos, &newu) // always add new utxo
|
||||||
fmt.Printf("...dupe ")
|
|
||||||
}
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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",
|
||||||
|
Loading…
Reference in New Issue
Block a user