good enough storage of spent txs
This commit is contained in:
parent
29d0c0cc6f
commit
1f40c7214e
@ -83,7 +83,7 @@ func (t *TxStore) IngestTx(tx *wire.MsgTx) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = t.ExpellTx(tx)
|
err = t.ExpellTx(tx, height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -115,7 +115,10 @@ 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
|
||||||
|
err := newu.SaveToDB(t.StateDB)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
t.Utxos = append(t.Utxos, newu)
|
t.Utxos = append(t.Utxos, newu)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -127,7 +130,7 @@ func (t *TxStore) AbsorbTx(tx *wire.MsgTx, height int32) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Expell money from wallet due to a tx
|
// Expell money from wallet due to a tx
|
||||||
func (t *TxStore) ExpellTx(tx *wire.MsgTx) error {
|
func (t *TxStore) ExpellTx(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")
|
||||||
}
|
}
|
||||||
@ -139,7 +142,11 @@ func (t *TxStore) ExpellTx(tx *wire.MsgTx) error {
|
|||||||
if myutxo.Op == in.PreviousOutPoint {
|
if myutxo.Op == in.PreviousOutPoint {
|
||||||
hits++
|
hits++
|
||||||
loss += myutxo.Txo.Value
|
loss += myutxo.Txo.Value
|
||||||
// delete from my utxo set
|
err := t.MarkSpent(&myutxo.Op, height, tx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// delete from my in-ram utxo set
|
||||||
t.Utxos = append(t.Utxos[:i], t.Utxos[i+1:]...)
|
t.Utxos = append(t.Utxos[:i], t.Utxos[i+1:]...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/wire"
|
||||||
|
|
||||||
"github.com/boltdb/bolt"
|
"github.com/boltdb/bolt"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -26,8 +28,32 @@ func (u *Utxo) SaveToDB(dbx *bolt.DB) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ts *TxStore) LoadUtxos() error {
|
func (ts *TxStore) MarkSpent(op *wire.OutPoint, h int32, stx *wire.MsgTx) error {
|
||||||
|
|
||||||
|
// we write in key = outpoint (32 hash, 4 index)
|
||||||
|
// value = spending txid
|
||||||
|
// if we care about the spending tx we can store that in another bucket.
|
||||||
|
return ts.StateDB.Update(func(tx *bolt.Tx) error {
|
||||||
|
old := tx.Bucket(BKTOld)
|
||||||
|
opb, err := outPointToBytes(op)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err = binary.Write(&buf, binary.BigEndian, h)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sha := stx.TxSha()
|
||||||
|
err = old.Put(opb, sha.Bytes()) // write k:v outpoint:txid
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts *TxStore) LoadUtxos() error {
|
||||||
err := ts.StateDB.View(func(tx *bolt.Tx) error {
|
err := ts.StateDB.View(func(tx *bolt.Tx) error {
|
||||||
duf := tx.Bucket(BKTUtxos)
|
duf := tx.Bucket(BKTUtxos)
|
||||||
if duf == nil {
|
if duf == nil {
|
||||||
@ -41,7 +67,8 @@ func (ts *TxStore) LoadUtxos() error {
|
|||||||
duf.ForEach(func(k, v []byte) error {
|
duf.ForEach(func(k, v []byte) error {
|
||||||
// have to copy these here, otherwise append will crash it.
|
// have to copy these here, otherwise append will crash it.
|
||||||
// not quite sure why but append does weird stuff I guess.
|
// not quite sure why but append does weird stuff I guess.
|
||||||
if spent.Get(k) == nil { // if it's not in the spent bucket
|
stx := spent.Get(k)
|
||||||
|
if stx == nil { // if it's not in the spent bucket
|
||||||
// create a new utxo
|
// create a new utxo
|
||||||
x := make([]byte, len(k)+len(v))
|
x := make([]byte, len(k)+len(v))
|
||||||
copy(x, k)
|
copy(x, k)
|
||||||
@ -52,6 +79,9 @@ func (ts *TxStore) LoadUtxos() error {
|
|||||||
}
|
}
|
||||||
// and add it to ram
|
// and add it to ram
|
||||||
ts.Utxos = append(ts.Utxos, newU)
|
ts.Utxos = append(ts.Utxos, newU)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("had utxo %x but spent by tx %x...\n",
|
||||||
|
k, stx[:8])
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@ -63,6 +93,21 @@ func (ts *TxStore) LoadUtxos() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// outPointToBytes turns an outpoint into 36 bytes.
|
||||||
|
func outPointToBytes(op *wire.OutPoint) ([]byte, error) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
_, err := buf.Write(op.Hash.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// write 4 byte outpoint index within the tx to spend
|
||||||
|
err = binary.Write(&buf, binary.BigEndian, op.Index)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
// ToBytes turns a Utxo into some bytes.
|
// ToBytes turns a Utxo into some bytes.
|
||||||
// note that the txid is the first 36 bytes and in our use cases will be stripped
|
// note that the txid is the first 36 bytes and in our use cases will be stripped
|
||||||
// off, but is left here for other applications
|
// off, but is left here for other applications
|
||||||
|
Loading…
Reference in New Issue
Block a user