From ee4dd8aaa084e0f56ad42652f2435f6cbdad1781 Mon Sep 17 00:00:00 2001 From: Tadge Dryja Date: Sat, 13 Feb 2016 14:03:11 -0800 Subject: [PATCH] trying to get witness coinbases to validate (they don't) --- shell.go | 8 ++++---- uspv/eight333.go | 41 ++++++++++++++++++++++++++++++++++++++--- uspv/hardmode.go | 48 +++++++++++++----------------------------------- uspv/init.go | 2 ++ uspv/txstore.go | 9 ++++++++- 5 files changed, 65 insertions(+), 43 deletions(-) diff --git a/shell.go b/shell.go index 3654cf72..5eb8057b 100644 --- a/shell.go +++ b/shell.go @@ -69,10 +69,10 @@ func shell() { } // once we're connected, initiate headers sync - err = SCon.AskForHeaders() - if err != nil { - log.Fatal(err) - } + // err = SCon.AskForHeaders() + // if err != nil { + // log.Fatal(err) + // } // main shell loop for { diff --git a/uspv/eight333.go b/uspv/eight333.go index 180d3767..533b87d6 100644 --- a/uspv/eight333.go +++ b/uspv/eight333.go @@ -118,7 +118,8 @@ func (s *SPVCon) IngestMerkleBlock(m *wire.MsgMerkleBlock) { if !hah.blockhash.IsEqual(&newMerkBlockSha) { log.Printf("merkle block out of order got %s expect %s", m.Header.BlockSha().String(), hah.blockhash.String()) - log.Printf("has %d hashes", len(m.Hashes)) + log.Printf("has %d hashes %d txs flags: %x", + len(m.Hashes), m.Transactions, m.Flags) return } @@ -283,6 +284,40 @@ func (s *SPVCon) AskForHeaders() error { return nil } +// AskForOneBlock is for testing only, so you can ask for a specific block height +// and see what goes wrong +func (s *SPVCon) AskForOneBlock(h int32) error { + var hdr wire.BlockHeader + var err error + + dbTip := int32(h) + s.headerMutex.Lock() // seek to header we need + _, err = s.headerFile.Seek(int64((dbTip)*80), os.SEEK_SET) + if err != nil { + return err + } + err = hdr.Deserialize(s.headerFile) // read header, done w/ file for now + s.headerMutex.Unlock() // unlock after reading 1 header + if err != nil { + log.Printf("header deserialize error!\n") + return err + } + + bHash := hdr.BlockSha() + // create inventory we're asking for + iv1 := wire.NewInvVect(wire.InvTypeWitnessBlock, &bHash) + gdataMsg := wire.NewMsgGetData() + // add inventory + err = gdataMsg.AddInvVect(iv1) + if err != nil { + return err + } + hah := NewRootAndHeight(bHash, h) + s.outMsgQueue <- gdataMsg + s.blockQueue <- hah // push height and mroot of requested block on queue + return nil +} + // AskForMerkBlocks requests blocks from current to last // right now this asks for 1 block per getData message. // Maybe it's faster to ask for many in a each message? @@ -347,9 +382,9 @@ func (s *SPVCon) AskForBlocks() error { iv1 := new(wire.InvVect) // if hardmode, ask for legit blocks, none of this ralphy stuff if s.HardMode { - iv1 = wire.NewInvVect(wire.InvTypeBlock, &bHash) + iv1 = wire.NewInvVect(wire.InvTypeWitnessBlock, &bHash) } else { // ah well - iv1 = wire.NewInvVect(wire.InvTypeFilteredBlock, &bHash) + iv1 = wire.NewInvVect(wire.InvTypeFilteredWitnessBlock, &bHash) } gdataMsg := wire.NewMsgGetData() // add inventory diff --git a/uspv/hardmode.go b/uspv/hardmode.go index 7cd62c1e..c5d99f5f 100644 --- a/uspv/hardmode.go +++ b/uspv/hardmode.go @@ -1,9 +1,9 @@ package uspv import ( + "bytes" "fmt" "log" - "os" "sync" "github.com/btcsuite/btcd/wire" @@ -24,6 +24,8 @@ func BlockRootOK(blk wire.MsgBlock) bool { for len(shas) > 1 { // calculate merkle root. Terse, eh? shas = append(shas[2:], MakeMerkleParent(shas[0], shas[1])) } // auto recognizes coinbase-only blocks + fmt.Printf("MRs calcd %s given %s\n", + shas[0].String(), blk.Header.MerkleRoot.String()) return blk.Header.MerkleRoot.IsEqual(shas[0]) } @@ -31,7 +33,16 @@ func BlockRootOK(blk wire.MsgBlock) bool { // different enough that it's better to have 2 separate functions func (s *SPVCon) IngestBlock(m *wire.MsgBlock) { var err error - + var buf bytes.Buffer + m.SerializeWitness(&buf) + fmt.Printf("block hex %x\n", buf.Bytes()) + for i, tx := range m.Transactions { + // if i > 0 { + fmt.Printf("wtxid: %s\n", tx.WTxSha()) + fmt.Printf("txid: %s\n", tx.TxSha()) + fmt.Printf("%d %s", i, TxToString(tx)) + // } + } ok := BlockRootOK(*m) // check block self-consistency if !ok { fmt.Printf("block %s not OK!!11\n", m.BlockSha().String()) @@ -59,7 +70,6 @@ func (s *SPVCon) IngestBlock(m *wire.MsgBlock) { var wg sync.WaitGroup wg.Add(len(m.Transactions)) for i, tx := range m.Transactions { - go func() { hits, err := s.TS.Ingest(tx, hah.height) if err != nil { @@ -99,35 +109,3 @@ func (s *SPVCon) IngestBlock(m *wire.MsgBlock) { } return } - -func (s *SPVCon) AskForOneBlock(h int32) error { - var hdr wire.BlockHeader - var err error - - dbTip := int32(h) - s.headerMutex.Lock() // seek to header we need - _, err = s.headerFile.Seek(int64((dbTip)*80), os.SEEK_SET) - if err != nil { - return err - } - err = hdr.Deserialize(s.headerFile) // read header, done w/ file for now - s.headerMutex.Unlock() // unlock after reading 1 header - if err != nil { - log.Printf("header deserialize error!\n") - return err - } - - bHash := hdr.BlockSha() - // create inventory we're asking for - iv1 := wire.NewInvVect(wire.InvTypeBlock, &bHash) - gdataMsg := wire.NewMsgGetData() - // add inventory - err = gdataMsg.AddInvVect(iv1) - if err != nil { - return err - } - - s.outMsgQueue <- gdataMsg - - return nil -} diff --git a/uspv/init.go b/uspv/init.go index 4dc84556..4fb3844a 100644 --- a/uspv/init.go +++ b/uspv/init.go @@ -49,6 +49,8 @@ func OpenSPV(remoteNode string, hfn, dbfn string, } // must set this to enable SPV stuff myMsgVer.AddService(wire.SFNodeBloom) + // set this to enable segWit + myMsgVer.AddService(wire.SFNodeWitness) // this actually sends n, err := wire.WriteMessageN(s.con, myMsgVer, s.localVersion, s.TS.Param.Net) if err != nil { diff --git a/uspv/txstore.go b/uspv/txstore.go index 17282bfb..ed6b555e 100644 --- a/uspv/txstore.go +++ b/uspv/txstore.go @@ -133,7 +133,8 @@ func CheckDoubleSpends( // TxToString prints out some info about a transaction. for testing / debugging func TxToString(tx *wire.MsgTx) string { - str := fmt.Sprintf("\t - Tx %s\n", tx.TxSha().String()) + str := fmt.Sprintf("\t size %d wsize %d Tx %s\n", + tx.SerializeSize(), tx.SerializeSizeWitness(), 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) @@ -146,6 +147,12 @@ func TxToString(tx *wire.MsgTx) string { str += fmt.Sprintf("output %d nil (WARNING)\n", i) } } + for i, wit := range tx.TxWitness { + if wit.ScriptWitness != nil { + str += fmt.Sprintf("Witness %d: %x\n", i, wit.ScriptWitness) + } + } + return str }