remove waitgroups from ingest block

It doesn't work; can ingest out of order within a block,
so if a block has gain then loss, you might read it as loss
then gains, missing the loss.
Also, tryna implement p2wpkh
This commit is contained in:
Tadge Dryja 2016-02-17 23:16:17 -08:00
parent 0d3639435f
commit a175e098fa
4 changed files with 74 additions and 40 deletions

@ -61,7 +61,7 @@ func shell() {
log.Fatal(err) log.Fatal(err)
} }
if tip == 0 { // DB has never been used, set to birthday if tip == 0 { // DB has never been used, set to birthday
tip = 1234 // hardcoded; later base on keyfile date? tip = 20000 // hardcoded; later base on keyfile date?
err = SCon.TS.SetDBSyncHeight(tip) err = SCon.TS.SetDBSyncHeight(tip)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
@ -254,7 +254,11 @@ func Send(args []string) error {
} }
// need args, fail // need args, fail
if len(args) < 2 { if len(args) < 2 {
return fmt.Errorf("need args: ssend amount(satoshis) address") return fmt.Errorf("need args: ssend amount(satoshis) address wit?")
}
var wit bool // whether to send to p2wpkh
if len(args) > 2 {
wit = true
} }
amt, err := strconv.ParseInt(args[0], 10, 64) amt, err := strconv.ParseInt(args[0], 10, 64)
if err != nil { if err != nil {
@ -270,7 +274,8 @@ func Send(args []string) error {
} }
fmt.Printf("send %d to address: %s \n", fmt.Printf("send %d to address: %s \n",
amt, adr.String()) amt, adr.String())
err = SendCoins(SCon, adr, amt)
err = SendCoins(SCon, adr, amt, wit)
if err != nil { if err != nil {
return err return err
} }
@ -278,7 +283,10 @@ func Send(args []string) error {
} }
// SendCoins does send coins, but it's very rudimentary // SendCoins does send coins, but it's very rudimentary
func SendCoins(s uspv.SPVCon, adr btcutil.Address, sendAmt int64) error { // wit makes it into p2wpkh. Which is not yet spendable.
func SendCoins(
s uspv.SPVCon, adr btcutil.Address, sendAmt int64, wit bool) error {
var err error var err error
var score int64 var score int64
allUtxos, err := s.TS.GetAllUtxos() allUtxos, err := s.TS.GetAllUtxos()
@ -297,10 +305,19 @@ func SendCoins(s uspv.SPVCon, adr btcutil.Address, sendAmt int64) error {
tx := wire.NewMsgTx() // make new tx tx := wire.NewMsgTx() // make new tx
// make address script 76a914...88ac // make address script 76a914...88ac
adrScript, err := txscript.PayToAddrScript(adr) var adrScript []byte
if wit {
adrScript, err = uspv.P2wpkhScript(adr)
if err != nil { if err != nil {
return err return err
} }
} else { // non-wit, use old p2pkh
adrScript, err = txscript.PayToAddrScript(adr)
if err != nil {
return err
}
}
// make user specified txout and add to tx // make user specified txout and add to tx
txout := wire.NewTxOut(sendAmt, adrScript) txout := wire.NewTxOut(sendAmt, adrScript)
tx.AddTxOut(txout) tx.AddTxOut(txout)

@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"log" "log"
"sync"
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
) )
@ -123,13 +122,11 @@ func (s *SPVCon) IngestBlock(m *wire.MsgBlock) {
// var buf bytes.Buffer // var buf bytes.Buffer
// m.SerializeWitness(&buf) // m.SerializeWitness(&buf)
// fmt.Printf("block hex %x\n", buf.Bytes()) // fmt.Printf("block hex %x\n", buf.Bytes())
for _, tx := range m.Transactions { // for _, tx := range m.Transactions {
// if i > 0 { // fmt.Printf("wtxid: %s\n", tx.WTxSha())
fmt.Printf("wtxid: %s\n", tx.WTxSha()) // fmt.Printf(" txid: %s\n", tx.TxSha())
fmt.Printf(" txid: %s\n", tx.TxSha())
// fmt.Printf("%d %s", i, TxToString(tx)) // fmt.Printf("%d %s", i, TxToString(tx))
// } // }
}
ok := BlockOK(*m) // check block self-consistency ok := BlockOK(*m) // check block self-consistency
if !ok { if !ok {
fmt.Printf("block %s not OK!!11\n", m.BlockSha().String()) fmt.Printf("block %s not OK!!11\n", m.BlockSha().String())
@ -154,11 +151,7 @@ func (s *SPVCon) IngestBlock(m *wire.MsgBlock) {
// iterate through all txs in the block, looking for matches. // iterate through all txs in the block, looking for matches.
// this is slow and can be sped up by doing in-ram filters client side. // this is slow and can be sped up by doing in-ram filters client side.
// kindof a pain to implement though and it's fast enough for now. // kindof a pain to implement though and it's fast enough for now.
var wg sync.WaitGroup
wg.Add(len(m.Transactions))
for i, tx := range m.Transactions { for i, tx := range m.Transactions {
go func() {
defer wg.Done()
hits, err := s.TS.Ingest(tx, hah.height) hits, err := s.TS.Ingest(tx, hah.height)
if err != nil { if err != nil {
log.Printf("Incoming Tx error: %s\n", err.Error()) log.Printf("Incoming Tx error: %s\n", err.Error())
@ -168,9 +161,7 @@ func (s *SPVCon) IngestBlock(m *wire.MsgBlock) {
log.Printf("block %d tx %d %s ingested and matches %d utxo/adrs.", log.Printf("block %d tx %d %s ingested and matches %d utxo/adrs.",
hah.height, i, tx.TxSha().String(), hits) hah.height, i, tx.TxSha().String(), hits)
} }
}()
} }
wg.Wait()
// write to db that we've sync'd to the height indicated in the // write to db that we've sync'd to the height indicated in the
// merkle block. This isn't QUITE true since we haven't actually gotten // merkle block. This isn't QUITE true since we haven't actually gotten

@ -95,7 +95,6 @@ func (s *SPVCon) fPositiveHandler() {
select { select {
case x := <-s.fPositives: case x := <-s.fPositives:
fpAccumulator += x fpAccumulator += x
default: default:
break finClear break finClear
} }
@ -181,10 +180,10 @@ func (s *SPVCon) GetDataHandler(m *wire.MsgGetData) {
for i, thing := range m.InvList { for i, thing := range m.InvList {
log.Printf("\t%d)%s : %s", log.Printf("\t%d)%s : %s",
i, thing.Type.String(), thing.Hash.String()) i, thing.Type.String(), thing.Hash.String())
if thing.Type != wire.InvTypeTx { // refuse non-tx reqs
log.Printf("We only respond to tx requests, ignoring") // separate wittx and tx. needed / combine?
continue // does the same thing right now
} if thing.Type == wire.InvTypeWitnessTx {
tx, err := s.TS.GetTx(&thing.Hash) tx, err := s.TS.GetTx(&thing.Hash)
if err != nil { if err != nil {
log.Printf("error getting tx %s: %s", log.Printf("error getting tx %s: %s",
@ -192,6 +191,21 @@ func (s *SPVCon) GetDataHandler(m *wire.MsgGetData) {
} }
s.outMsgQueue <- tx s.outMsgQueue <- tx
sent++ sent++
continue
}
if thing.Type == wire.InvTypeTx {
tx, err := s.TS.GetTx(&thing.Hash)
if err != nil {
log.Printf("error getting tx %s: %s",
thing.Hash.String(), err.Error())
}
s.outMsgQueue <- tx
sent++
continue
}
// didn't match, so it's not something we're responding to
log.Printf("We only respond to tx requests, ignoring")
} }
log.Printf("sent %d of %d requested items", sent, len(m.InvList)) log.Printf("sent %d of %d requested items", sent, len(m.InvList))
} }

@ -7,6 +7,7 @@ import (
"github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
"github.com/btcsuite/btcutil/bloom" "github.com/btcsuite/btcutil/bloom"
"github.com/btcsuite/btcutil/hdkeychain" "github.com/btcsuite/btcutil/hdkeychain"
"github.com/btcsuite/btcutil/txsort" "github.com/btcsuite/btcutil/txsort"
@ -41,6 +42,17 @@ func (s *SPVCon) Rebroadcast() {
return return
} }
func P2wpkhScript(adr btcutil.Address) ([]byte, error) {
switch adr := adr.(type) {
case *btcutil.AddressPubKeyHash:
sb := txscript.NewScriptBuilder()
sb.AddOp(txscript.OP_0)
sb.AddData(adr.ScriptAddress())
return sb.Script()
}
return nil, fmt.Errorf("%s is not pkh address", adr.String())
}
func (s *SPVCon) NewOutgoingTx(tx *wire.MsgTx) error { func (s *SPVCon) NewOutgoingTx(tx *wire.MsgTx) error {
txid := tx.TxSha() txid := tx.TxSha()
// assign height of zero for txs we create // assign height of zero for txs we create
@ -53,7 +65,7 @@ func (s *SPVCon) NewOutgoingTx(tx *wire.MsgTx) error {
return err return err
} }
// make an inv message instead of a tx message to be polite // make an inv message instead of a tx message to be polite
iv1 := wire.NewInvVect(wire.InvTypeTx, &txid) iv1 := wire.NewInvVect(wire.InvTypeWitnessTx, &txid)
invMsg := wire.NewMsgInv() invMsg := wire.NewMsgInv()
err = invMsg.AddInvVect(iv1) err = invMsg.AddInvVect(iv1)
if err != nil { if err != nil {