diff --git a/uspv/eight333.go b/uspv/eight333.go index 22f582e4a..5c2e459d1 100644 --- a/uspv/eight333.go +++ b/uspv/eight333.go @@ -368,7 +368,7 @@ func (s *SPVCon) AskForMerkBlocks(current, last int32) error { var hdr wire.BlockHeader // if last is 0, that means go as far as we can if last == 0 { - n, err := s.headerFile.Seek(-80, os.SEEK_END) + n, err := s.headerFile.Seek(0, os.SEEK_END) if err != nil { return err } @@ -392,8 +392,8 @@ func (s *SPVCon) AskForMerkBlocks(current, last int32) error { } // loop through all heights where we want merkleblocks. for current < last { - // check if we need to update filter... every 5 new inputs...? - if track+4 < len(s.TS.Utxos) { + // check if we need to update filter... diff of 5 utxos...? + if track < len(s.TS.Utxos)-4 || track > len(s.TS.Utxos)+4 { track = len(s.TS.Utxos) filt, err := s.TS.GimmeFilter() if err != nil { diff --git a/uspv/txstore.go b/uspv/txstore.go index 23c4b35ce..c9aaa6569 100644 --- a/uspv/txstore.go +++ b/uspv/txstore.go @@ -140,11 +140,15 @@ func (t *TxStore) AbsorbTx(tx *wire.MsgTx, height int32) error { newop.Hash = tx.TxSha() newop.Index = uint32(i) newu.Op = newop - err := newu.SaveToDB(t.StateDB) + dupe, err := newu.SaveToDB(t.StateDB) if err != nil { return err } - t.Utxos = append(t.Utxos, newu) + if !dupe { // only save to DB if new txid + t.Utxos = append(t.Utxos, newu) + } else { + fmt.Printf("...dupe ") + } break } } diff --git a/uspv/utxodb.go b/uspv/utxodb.go index 68da11b39..4e701cfc8 100644 --- a/uspv/utxodb.go +++ b/uspv/utxodb.go @@ -7,6 +7,7 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" + "github.com/btcsuite/btcutil/hdkeychain" "github.com/boltdb/bolt" ) @@ -50,7 +51,7 @@ func (ts *TxStore) NewAdr() (*btcutil.AddressPubKeyHash, error) { return nil, fmt.Errorf("nil param") } n := uint32(len(ts.Adrs)) - priv, err := ts.rootPrivKey.Child(n) // + hdkeychain.HardenedKeyStart) + priv, err := ts.rootPrivKey.Child(n + hdkeychain.HardenedKeyStart) if err != nil { return nil, err } @@ -84,7 +85,7 @@ func (ts *TxStore) NewAdr() (*btcutil.AddressPubKeyHash, error) { func (ts *TxStore) PopulateAdrs(lastKey uint32) error { for k := uint32(0); k < lastKey; k++ { - priv, err := ts.rootPrivKey.Child(k) // + hdkeychain.HardenedKeyStart) + priv, err := ts.rootPrivKey.Child(k + hdkeychain.HardenedKeyStart) if err != nil { return err } @@ -99,16 +100,26 @@ func (ts *TxStore) PopulateAdrs(lastKey uint32) error { return nil } -func (u *Utxo) SaveToDB(dbx *bolt.DB) error { - return dbx.Update(func(tx *bolt.Tx) error { +// 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 + 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 + } // key : val is txid:everything else return duf.Put(b[:36], b[36:]) }) + if err != nil { + return false, err + } + return dupe, nil } func (ts *TxStore) MarkSpent(op *wire.OutPoint, h int32, stx *wire.MsgTx) error {