add getalltxs, dup checks
Start of double spend detection for mempool and reorgs
This commit is contained in:
parent
25d90f5345
commit
63b5926e01
18
shell.go
18
shell.go
@ -144,11 +144,29 @@ func Shellparse(cmdslice []string) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if cmd == "txs" {
|
||||
err = Txs(args)
|
||||
if err != nil {
|
||||
fmt.Printf("txs error: %s\n", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Printf("Command not recognized. type help for command list.\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
func Txs(args []string) error {
|
||||
alltx, err := SCon.TS.GetAllTxs()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i, tx := range alltx {
|
||||
fmt.Printf("tx %d %s\n", i, uspv.TxToString(tx))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Bal prints out your score.
|
||||
func Bal(args []string) error {
|
||||
if SCon.TS == nil {
|
||||
|
@ -100,9 +100,40 @@ func (t *TxStore) GimmeFilter() (*bloom.Filter, error) {
|
||||
return f, nil
|
||||
}
|
||||
|
||||
// GetDoubleSpends takes a transaction and compares it with
|
||||
// all transactions in the db. It returns a slice of all txids in the db
|
||||
// which are double spent by the received tx.
|
||||
func GetDoubleSpends(
|
||||
argTx *wire.MsgTx, txs []*wire.MsgTx) ([]*wire.ShaHash, error) {
|
||||
|
||||
var dubs []*wire.ShaHash // slice of all double-spent txs
|
||||
argTxid := argTx.TxSha()
|
||||
|
||||
for _, compTx := range txs {
|
||||
compTxid := compTx.TxSha()
|
||||
// check if entire tx is dup
|
||||
if argTxid.IsEqual(&compTxid) {
|
||||
return nil, fmt.Errorf("tx %s is dup", argTxid.String())
|
||||
}
|
||||
// not dup, iterate through inputs of argTx
|
||||
for _, argIn := range argTx.TxIn {
|
||||
// iterate through inputs of compTx
|
||||
for _, compIn := range compTx.TxIn {
|
||||
if OutPointsEqual(
|
||||
argIn.PreviousOutPoint, compIn.PreviousOutPoint) {
|
||||
// found double spend
|
||||
dubs = append(dubs, &compTxid)
|
||||
break // back to argIn loop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return dubs, nil
|
||||
}
|
||||
|
||||
// TxToString prints out some info about a transaction. for testing / debugging
|
||||
func TxToString(tx *wire.MsgTx) string {
|
||||
str := "\t\t\t - Tx - \n"
|
||||
str := fmt.Sprintf("\t - Tx %s\n", tx.TxSha().String())
|
||||
for i, in := range tx.TxIn {
|
||||
str += fmt.Sprintf("Input %d: %s\n", i, in.PreviousOutPoint.String())
|
||||
str += fmt.Sprintf("SigScript for input %d: %x\n", i, in.SignatureScript)
|
||||
|
@ -248,6 +248,33 @@ func (ts *TxStore) GetTx(txid *wire.ShaHash) (*wire.MsgTx, error) {
|
||||
return rtx, nil
|
||||
}
|
||||
|
||||
// GetTx takes a txid and returns the transaction. If we have it.
|
||||
func (ts *TxStore) GetAllTxs() ([]*wire.MsgTx, error) {
|
||||
var rtxs []*wire.MsgTx
|
||||
|
||||
err := ts.StateDB.View(func(btx *bolt.Tx) error {
|
||||
txns := btx.Bucket(BKTTxns)
|
||||
if txns == nil {
|
||||
return fmt.Errorf("no transactions in db")
|
||||
}
|
||||
|
||||
return txns.ForEach(func(k, v []byte) error {
|
||||
tx := wire.NewMsgTx()
|
||||
buf := bytes.NewBuffer(v)
|
||||
err := tx.Deserialize(buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rtxs = append(rtxs, tx)
|
||||
return nil
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return rtxs, nil
|
||||
}
|
||||
|
||||
// GetPendingInv returns an inv message containing all txs known to the
|
||||
// db which are at height 0 (not known to be confirmed).
|
||||
// This can be useful on startup or to rebroadcast unconfirmed txs.
|
||||
|
Loading…
Reference in New Issue
Block a user