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
|
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")
|
fmt.Printf("Command not recognized. type help for command list.\n")
|
||||||
return nil
|
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.
|
// Bal prints out your score.
|
||||||
func Bal(args []string) error {
|
func Bal(args []string) error {
|
||||||
if SCon.TS == nil {
|
if SCon.TS == nil {
|
||||||
|
@ -100,9 +100,40 @@ func (t *TxStore) GimmeFilter() (*bloom.Filter, error) {
|
|||||||
return f, nil
|
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
|
// TxToString prints out some info about a transaction. for testing / debugging
|
||||||
func TxToString(tx *wire.MsgTx) string {
|
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 {
|
for i, in := range tx.TxIn {
|
||||||
str += fmt.Sprintf("Input %d: %s\n", i, in.PreviousOutPoint.String())
|
str += fmt.Sprintf("Input %d: %s\n", i, in.PreviousOutPoint.String())
|
||||||
str += fmt.Sprintf("SigScript for input %d: %x\n", i, in.SignatureScript)
|
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
|
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
|
// GetPendingInv returns an inv message containing all txs known to the
|
||||||
// db which are at height 0 (not known to be confirmed).
|
// db which are at height 0 (not known to be confirmed).
|
||||||
// This can be useful on startup or to rebroadcast unconfirmed txs.
|
// This can be useful on startup or to rebroadcast unconfirmed txs.
|
||||||
|
Loading…
Reference in New Issue
Block a user