update uspv, add function for height from header
still a bunch of problems getting utxo sets
This commit is contained in:
1 parent
24afe237db
commit
7dbf4a4a4f
4 files changed
+71
-18
No files matched your search
@@ -156,6 +156,45 @@ func (s *SPVCon) SendFilter(f *bloom.Filter) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HeightFromHeader gives you the block height given a 80 byte block header
|
||||||
|
// seems like looking for the merkle root is the best way to do this
|
||||||
|
func (s *SPVCon) HeightFromHeader(query wire.BlockHeader) (uint32, error) {
|
||||||
|
// start from the most recent and work back in time; even though that's
|
||||||
|
// kind of annoying it's probably a lot faster since things tend to have
|
||||||
|
// happened recently.
|
||||||
|
|
||||||
|
// seek to last header
|
||||||
|
lastPos, err := s.headerFile.Seek(-80, os.SEEK_END)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
height := lastPos / 80
|
||||||
|
|
||||||
|
var current wire.BlockHeader
|
||||||
|
|
||||||
|
for height > 0 {
|
||||||
|
// grab header from disk
|
||||||
|
err = current.Deserialize(s.headerFile)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
// check if merkle roots match
|
||||||
|
if current.MerkleRoot.IsEqual(&query.MerkleRoot) {
|
||||||
|
// if they do, great, return height
|
||||||
|
return uint32(height), nil
|
||||||
|
}
|
||||||
|
// skip back one header (2 because we just read one)
|
||||||
|
_, err = s.headerFile.Seek(-160, os.SEEK_CUR)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
// decrement height
|
||||||
|
height--
|
||||||
|
}
|
||||||
|
// finished for loop without finding match
|
||||||
|
return 0, fmt.Errorf("Header not found on disk")
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SPVCon) AskForHeaders() error {
|
func (s *SPVCon) AskForHeaders() error {
|
||||||
var hdr wire.BlockHeader
|
var hdr wire.BlockHeader
|
||||||
ghdr := wire.NewMsgGetHeaders()
|
ghdr := wire.NewMsgGetHeaders()
|
||||||
@@ -201,6 +240,7 @@ func (s *SPVCon) AskForHeaders() error {
|
|||||||
|
|
||||||
func (s *SPVCon) IngestHeaders(m *wire.MsgHeaders) (bool, error) {
|
func (s *SPVCon) IngestHeaders(m *wire.MsgHeaders) (bool, error) {
|
||||||
var err error
|
var err error
|
||||||
|
// seek to last header
|
||||||
_, err = s.headerFile.Seek(-80, os.SEEK_END)
|
_, err = s.headerFile.Seek(-80, os.SEEK_END)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
|||||||
@@ -77,6 +77,9 @@ func checkMBlock(m *wire.MsgMerkleBlock) ([]*wire.ShaHash, error) {
|
|||||||
if len(m.Flags) == 0 {
|
if len(m.Flags) == 0 {
|
||||||
return nil, fmt.Errorf("No flag bits")
|
return nil, fmt.Errorf("No flag bits")
|
||||||
}
|
}
|
||||||
|
if len(m.Hashes) < 2 { // nothing but the merkle root
|
||||||
|
return nil, nil // nothin.
|
||||||
|
}
|
||||||
var s []merkleNode // the stack
|
var s []merkleNode // the stack
|
||||||
var r []*wire.ShaHash // slice to return; txids we care about
|
var r []*wire.ShaHash // slice to return; txids we care about
|
||||||
|
|
||||||
|
|||||||
+10
-2
@@ -39,13 +39,21 @@ func (s *SPVCon) incomingMessageHandler() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Merkle block error: %s\n", err.Error())
|
log.Printf("Merkle block error: %s\n", err.Error())
|
||||||
return
|
return
|
||||||
// continue
|
|
||||||
}
|
}
|
||||||
fmt.Printf(" got %d txs ", len(txids))
|
fmt.Printf(" got %d txs ", len(txids))
|
||||||
// fmt.Printf(" = got %d txs from block %s\n",
|
// fmt.Printf(" = got %d txs from block %s\n",
|
||||||
// len(txids), m.Header.BlockSha().String())
|
// len(txids), m.Header.BlockSha().String())
|
||||||
|
var height uint32
|
||||||
|
if len(txids) > 0 {
|
||||||
|
// make sure block is in our store before adding txs
|
||||||
|
height, err = s.HeightFromHeader(m.Header)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Merkle block height error: %s\n", err.Error())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
for _, txid := range txids {
|
for _, txid := range txids {
|
||||||
err := s.TS.AddTxid(txid)
|
err := s.TS.AddTxid(txid, height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Txid store error: %s\n", err.Error())
|
log.Printf("Txid store error: %s\n", err.Error())
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-16
@@ -11,10 +11,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type TxStore struct {
|
type TxStore struct {
|
||||||
KnownTxids []*wire.ShaHash
|
OKTxids map[wire.ShaHash]uint32 // known good txids and their heights
|
||||||
Utxos []Utxo // stacks on stacks
|
|
||||||
Sum int64 // racks on racks
|
Utxos []Utxo // stacks on stacks
|
||||||
Adrs []MyAdr // endeavouring to acquire capital
|
Sum int64 // racks on racks
|
||||||
|
Adrs []MyAdr // endeavouring to acquire capital
|
||||||
}
|
}
|
||||||
|
|
||||||
type Utxo struct { // cash money.
|
type Utxo struct { // cash money.
|
||||||
@@ -30,6 +31,12 @@ type MyAdr struct { // an address I have the private key for
|
|||||||
KeyIdx uint32 // index for private key needed to sign / spend
|
KeyIdx uint32 // index for private key needed to sign / spend
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewTxStore() TxStore {
|
||||||
|
var txs TxStore
|
||||||
|
txs.OKTxids = make(map[wire.ShaHash]uint32)
|
||||||
|
return txs
|
||||||
|
}
|
||||||
|
|
||||||
// add addresses into the TxStore
|
// add addresses into the TxStore
|
||||||
func (t *TxStore) AddAdr(a btcutil.Address, kidx uint32) {
|
func (t *TxStore) AddAdr(a btcutil.Address, kidx uint32) {
|
||||||
var ma MyAdr
|
var ma MyAdr
|
||||||
@@ -40,11 +47,11 @@ func (t *TxStore) AddAdr(a btcutil.Address, kidx uint32) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add txid of interest
|
// add txid of interest
|
||||||
func (t *TxStore) AddTxid(txid *wire.ShaHash) error {
|
func (t *TxStore) AddTxid(txid *wire.ShaHash, height uint32) error {
|
||||||
if txid == nil {
|
if txid == nil {
|
||||||
return fmt.Errorf("tried to add nil txid")
|
return fmt.Errorf("tried to add nil txid")
|
||||||
}
|
}
|
||||||
t.KnownTxids = append(t.KnownTxids, txid)
|
t.OKTxids[*txid] = height
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,19 +69,13 @@ func (t *TxStore) GimmeFilter() (*bloom.Filter, error) {
|
|||||||
|
|
||||||
// Ingest a tx into wallet, dealing with both gains and losses
|
// Ingest a tx into wallet, dealing with both gains and losses
|
||||||
func (t *TxStore) IngestTx(tx *wire.MsgTx) error {
|
func (t *TxStore) IngestTx(tx *wire.MsgTx) error {
|
||||||
var match bool
|
|
||||||
inTxid := tx.TxSha()
|
inTxid := tx.TxSha()
|
||||||
for _, ktxid := range t.KnownTxids {
|
height, ok := t.OKTxids[inTxid]
|
||||||
if inTxid.IsEqual(ktxid) {
|
if !ok {
|
||||||
match = true
|
|
||||||
break // found tx match,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !match {
|
|
||||||
return fmt.Errorf("we don't care about tx %s", inTxid.String())
|
return fmt.Errorf("we don't care about tx %s", inTxid.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
err := t.AbsorbTx(tx)
|
err := t.AbsorbTx(tx, height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -87,7 +88,7 @@ func (t *TxStore) IngestTx(tx *wire.MsgTx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Absorb money into wallet from a tx
|
// Absorb money into wallet from a tx
|
||||||
func (t *TxStore) AbsorbTx(tx *wire.MsgTx) error {
|
func (t *TxStore) AbsorbTx(tx *wire.MsgTx, height uint32) error {
|
||||||
if tx == nil {
|
if tx == nil {
|
||||||
return fmt.Errorf("Tried to add nil tx")
|
return fmt.Errorf("Tried to add nil tx")
|
||||||
}
|
}
|
||||||
@@ -102,6 +103,7 @@ func (t *TxStore) AbsorbTx(tx *wire.MsgTx) error {
|
|||||||
hits++
|
hits++
|
||||||
acq += out.Value
|
acq += out.Value
|
||||||
var newu Utxo
|
var newu Utxo
|
||||||
|
newu.AtHeight = height
|
||||||
newu.KeyIdx = a.KeyIdx
|
newu.KeyIdx = a.KeyIdx
|
||||||
newu.Txo = *out
|
newu.Txo = *out
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user