From 29a8e810298ef83408fd223b56d2f0a2e044850d Mon Sep 17 00:00:00 2001 From: Tadge Dryja Date: Fri, 15 Jan 2016 02:40:56 -0800 Subject: [PATCH] spv sync works but more to add --- README.md | 8 ++++++++ uspv/eight333.go | 32 +++++++++++++++++++++++++++++++- uspv/msghandler.go | 25 ++++++++++++++++++------- uspv/txstore.go | 33 ++++++++++++++++++++++++++++----- 4 files changed, 85 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index e69de29b..c5c3ae94 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,8 @@ +# lnd - lightning network daemon + +This repo is preliminary work on a lightning network peer to peer node and wallet. + +It currently is being designed for testnet-L, a test network where all* txids are normalized. This fixes malleability but isn't something that can be cleanly done to the existing bitcoin network. + +It is not yet functional, but we hope to have a proof of concept on testnet-L soon. + diff --git a/uspv/eight333.go b/uspv/eight333.go index 473578e0..7eb9325c 100644 --- a/uspv/eight333.go +++ b/uspv/eight333.go @@ -41,9 +41,11 @@ type SPVCon struct { WBytes uint64 // total bytes written RBytes uint64 // total bytes read + + TS *TxStore } -func (s *SPVCon) Open(remoteNode string, hfn string) error { +func (s *SPVCon) Open(remoteNode string, hfn string, inTs *TxStore) error { // open header file err := s.openHeaderFile(headerFileName) if err != nil { @@ -59,6 +61,8 @@ func (s *SPVCon) Open(remoteNode string, hfn string) error { s.localVersion = VERSION s.netType = NETVERSION + s.TS = inTs + myMsgVer, err := wire.NewMsgVersionFromConn(s.con, 0, 0) if err != nil { return err @@ -270,6 +274,32 @@ func (s *SPVCon) IngestHeaders(m *wire.MsgHeaders) (bool, error) { return true, nil } +func (s *SPVCon) AskForMerkBlocks(current, last uint32) error { + var hdr wire.BlockHeader + _, err := s.headerFile.Seek(int64(current*80), os.SEEK_SET) + if err != nil { + return err + } + for current < last { + err = hdr.Deserialize(s.headerFile) + if err != nil { + return err + } + current++ + + bHash := hdr.BlockSha() + iv1 := wire.NewInvVect(wire.InvTypeFilteredBlock, &bHash) + gdataMsg := wire.NewMsgGetData() + err = gdataMsg.AddInvVect(iv1) + if err != nil { + return err + } + s.outMsgQueue <- gdataMsg + } + + return nil +} + func sendMBReq(cn net.Conn, blkhash wire.ShaHash) error { iv1 := wire.NewInvVect(wire.InvTypeFilteredBlock, &blkhash) gdataB := wire.NewMsgGetData() diff --git a/uspv/msghandler.go b/uspv/msghandler.go index 87714827..76e7f1b9 100644 --- a/uspv/msghandler.go +++ b/uspv/msghandler.go @@ -31,17 +31,25 @@ func (s *SPVCon) incomingMessageHandler() { case *wire.MsgPong: log.Printf("Got a pong response. OK.\n") case *wire.MsgMerkleBlock: - log.Printf("Got merkle block message. Will verify.\n") - fmt.Printf("%d flag bytes, %d txs, %d hashes", - len(m.Flags), m.Transactions, len(m.Hashes)) + + // log.Printf("Got merkle block message. Will verify.\n") + // fmt.Printf("%d flag bytes, %d txs, %d hashes", + // len(m.Flags), m.Transactions, len(m.Hashes)) txids, err := checkMBlock(m) if err != nil { log.Printf("Merkle block error: %s\n", err.Error()) return // continue } - fmt.Printf(" = got %d txs from block %s\n", - len(txids), m.Header.BlockSha().String()) + fmt.Printf(" got %d txs ", len(txids)) + // fmt.Printf(" = got %d txs from block %s\n", + // len(txids), m.Header.BlockSha().String()) + for _, txid := range txids { + err := s.TS.AddTxid(txid) + if err != nil { + log.Printf("Txid store error: %s\n", err.Error()) + } + } // nextReq <- true case *wire.MsgHeaders: @@ -54,8 +62,11 @@ func (s *SPVCon) incomingMessageHandler() { s.AskForHeaders() } case *wire.MsgTx: - - log.Printf("Got tx %s\n", m.TxSha().String()) + err := s.TS.IngestTx(m) + if err != nil { + log.Printf("Incoming Tx error: %s\n", err.Error()) + } + // log.Printf("Got tx %s\n", m.TxSha().String()) default: log.Printf("Got unknown message type %s\n", m.Command()) } diff --git a/uspv/txstore.go b/uspv/txstore.go index 1943914a..7d4f4e5a 100644 --- a/uspv/txstore.go +++ b/uspv/txstore.go @@ -11,7 +11,7 @@ import ( ) type TxStore struct { - KnownTxids []wire.ShaHash + KnownTxids []*wire.ShaHash Utxos []Utxo // stacks on stacks Sum int64 // racks on racks Adrs []MyAdr // endeavouring to acquire capital @@ -19,9 +19,10 @@ type TxStore struct { type Utxo struct { // cash money. // combo of outpoint and txout which has all the info needed to spend - Op wire.OutPoint - Txo wire.TxOut - KeyIdx uint32 // index for private key needed to sign / spend + Op wire.OutPoint + Txo wire.TxOut + AtHeight uint32 // block height where this tx was confirmed, 0 for unconf + KeyIdx uint32 // index for private key needed to sign / spend } type MyAdr struct { // an address I have the private key for @@ -38,6 +39,15 @@ func (t *TxStore) AddAdr(a btcutil.Address, kidx uint32) { return } +// add txid of interest +func (t *TxStore) AddTxid(txid *wire.ShaHash) error { + if txid == nil { + return fmt.Errorf("tried to add nil txid") + } + t.KnownTxids = append(t.KnownTxids, txid) + return nil +} + // ... or I'm gonna fade away func (t *TxStore) GimmeFilter() (*bloom.Filter, error) { if len(t.Adrs) == 0 { @@ -52,6 +62,18 @@ func (t *TxStore) GimmeFilter() (*bloom.Filter, error) { // Ingest a tx into wallet, dealing with both gains and losses func (t *TxStore) IngestTx(tx *wire.MsgTx) error { + var match bool + inTxid := tx.TxSha() + for _, ktxid := range t.KnownTxids { + if inTxid.IsEqual(ktxid) { + match = true + break // found tx match, + } + } + if !match { + return fmt.Errorf("we don't care about tx %s", inTxid.String()) + } + err := t.AbsorbTx(tx) if err != nil { return err @@ -60,6 +82,7 @@ func (t *TxStore) IngestTx(tx *wire.MsgTx) error { if err != nil { return err } + // fmt.Printf("ingested tx %s total amt %d\n", inTxid.String(), t.Sum) return nil } @@ -87,7 +110,7 @@ func (t *TxStore) AbsorbTx(tx *wire.MsgTx) error { newop.Index = uint32(i) newu.Op = newop - t.Utxos = append(t.Utxos) + t.Utxos = append(t.Utxos, newu) break } }