package uspv import ( "bytes" "fmt" "log" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil/bloom" "github.com/btcsuite/btcutil/hdkeychain" "github.com/btcsuite/btcutil/txsort" ) func (s *SPVCon) PongBack(nonce uint64) { mpong := wire.NewMsgPong(nonce) s.outMsgQueue <- mpong return } func (s *SPVCon) SendFilter(f *bloom.Filter) { s.outMsgQueue <- f.MsgFilterLoad() return } // Rebroadcast sends an inv message of all the unconfirmed txs the db is // aware of. This is called after every sync. Only txids so hopefully not // too annoying for nodes. func (s *SPVCon) Rebroadcast() { // get all unconfirmed txs invMsg, err := s.TS.GetPendingInv() if err != nil { log.Printf("Rebroadcast error: %s", err.Error()) } if len(invMsg.InvList) == 0 { // nothing to broadcast, so don't return } s.outMsgQueue <- invMsg return } func (s *SPVCon) NewOutgoingTx(tx *wire.MsgTx) error { txid := tx.TxSha() // assign height of zero for txs we create err := s.TS.AddTxid(&txid, 0) if err != nil { return err } _, err = s.TS.Ingest(tx, 0) // our own tx; don't keep track of false positives if err != nil { return err } // make an inv message instead of a tx message to be polite iv1 := wire.NewInvVect(wire.InvTypeTx, &txid) invMsg := wire.NewMsgInv() err = invMsg.AddInvVect(iv1) if err != nil { return err } s.outMsgQueue <- invMsg return nil } func (t *TxStore) SignThis(tx *wire.MsgTx) error { fmt.Printf("-= SignThis =-\n") // sort tx before signing. txsort.InPlaceSort(tx) sigs := make([][]byte, len(tx.TxIn)) // first iterate over each input for j, in := range tx.TxIn { for k := uint32(0); k < uint32(len(t.Adrs)); k++ { child, err := t.rootPrivKey.Child(k + hdkeychain.HardenedKeyStart) if err != nil { return err } myadr, err := child.Address(t.Param) if err != nil { return err } adrScript, err := txscript.PayToAddrScript(myadr) if err != nil { return err } if bytes.Equal(adrScript, in.SignatureScript) { fmt.Printf("Hit; key %d matches input %d. Signing.\n", k, j) priv, err := child.ECPrivKey() if err != nil { return err } sigs[j], err = txscript.SignatureScript( tx, j, in.SignatureScript, txscript.SigHashAll, priv, true) if err != nil { return err } break } } } for i, s := range sigs { if s != nil { tx.TxIn[i].SignatureScript = s } } return nil }