Skip to content

Commit e2c69ee

Browse files
committed
Initial draft of PR
Signed-off-by: Ononiwu Maureen <[email protected]>
1 parent d209c5e commit e2c69ee

File tree

9 files changed

+2082
-1094
lines changed

9 files changed

+2082
-1094
lines changed

blockmanager.go

Lines changed: 386 additions & 97 deletions
Large diffs are not rendered by default.

blockmanager_test.go

Lines changed: 905 additions & 905 deletions
Large diffs are not rendered by default.

headerfs/store.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ type BlockHeaderStore interface {
7474
// The information about the new header tip after truncation is
7575
// returned.
7676
RollbackLastBlock() (*BlockStamp, error)
77+
78+
// BlockLocatorFromHeight returns the block locator object based on the height
79+
// supplied as argument to the function.
80+
BlockLocatorFromHeight(uint32) (blockchain.BlockLocator, error)
7781
}
7882

7983
// headerBufPool is a pool of bytes.Buffer that will be re-used by the various
@@ -482,6 +486,25 @@ func (h *blockHeaderStore) LatestBlockLocator() (blockchain.BlockLocator, error)
482486
return h.blockLocatorFromHash(chainTipHash)
483487
}
484488

489+
// BlockLocatorFromHeight returns the block locator object based on the height
490+
// supplied as argument to the function.
491+
//
492+
// NOTE: Part of the BlockHeaderStore interface.
493+
func (h *blockHeaderStore) BlockLocatorFromHeight(height uint32) (blockchain.BlockLocator, error) {
494+
// Lock store for read.
495+
h.mtx.RLock()
496+
defer h.mtx.RUnlock()
497+
498+
blockheader, err := h.FetchHeaderByHeight(height)
499+
if err != nil {
500+
return nil, err
501+
}
502+
503+
blockHash := blockheader.BlockHash()
504+
505+
return h.blockLocatorFromHash(&blockHash)
506+
}
507+
485508
// BlockLocatorFromHash computes a block locator given a particular hash. The
486509
// standard Bitcoin algorithm to compute block locators are employed.
487510
func (h *blockHeaderStore) BlockLocatorFromHash(hash *chainhash.Hash) (

mock_store.go

Lines changed: 83 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,85 @@
11
package neutrino
22

3-
import (
4-
"fmt"
5-
6-
"github.com/btcsuite/btcd/blockchain"
7-
"github.com/btcsuite/btcd/chaincfg/chainhash"
8-
"github.com/btcsuite/btcd/wire"
9-
"github.com/lightninglabs/neutrino/headerfs"
10-
)
11-
12-
// mockBlockHeaderStore is an implementation of the BlockHeaderStore backed by
13-
// a simple map.
14-
type mockBlockHeaderStore struct {
15-
headers map[chainhash.Hash]wire.BlockHeader
16-
heights map[uint32]wire.BlockHeader
17-
}
18-
19-
// A compile-time check to ensure the mockBlockHeaderStore adheres to the
20-
// BlockHeaderStore interface.
21-
var _ headerfs.BlockHeaderStore = (*mockBlockHeaderStore)(nil)
22-
23-
// NewMockBlockHeaderStore returns a version of the BlockHeaderStore that's
24-
// backed by an in-memory map. This instance is meant to be used by callers
25-
// outside the package to unit test components that require a BlockHeaderStore
26-
// interface.
27-
func newMockBlockHeaderStore() *mockBlockHeaderStore {
28-
return &mockBlockHeaderStore{
29-
headers: make(map[chainhash.Hash]wire.BlockHeader),
30-
heights: make(map[uint32]wire.BlockHeader),
31-
}
32-
}
33-
34-
func (m *mockBlockHeaderStore) ChainTip() (*wire.BlockHeader,
35-
uint32, error) {
36-
37-
return nil, 0, nil
38-
}
39-
func (m *mockBlockHeaderStore) LatestBlockLocator() (
40-
blockchain.BlockLocator, error) {
41-
42-
return nil, nil
43-
}
44-
45-
func (m *mockBlockHeaderStore) FetchHeaderByHeight(height uint32) (
46-
*wire.BlockHeader, error) {
47-
48-
if header, ok := m.heights[height]; ok {
49-
return &header, nil
50-
}
51-
52-
return nil, headerfs.ErrHeightNotFound
53-
}
54-
55-
func (m *mockBlockHeaderStore) FetchHeaderAncestors(uint32,
56-
*chainhash.Hash) ([]wire.BlockHeader, uint32, error) {
57-
58-
return nil, 0, nil
59-
}
60-
func (m *mockBlockHeaderStore) HeightFromHash(*chainhash.Hash) (uint32, error) {
61-
return 0, nil
62-
}
63-
func (m *mockBlockHeaderStore) RollbackLastBlock() (*headerfs.BlockStamp,
64-
error) {
65-
66-
return nil, nil
67-
}
68-
69-
func (m *mockBlockHeaderStore) FetchHeader(h *chainhash.Hash) (
70-
*wire.BlockHeader, uint32, error) {
71-
72-
if header, ok := m.headers[*h]; ok {
73-
return &header, 0, nil
74-
}
75-
return nil, 0, fmt.Errorf("not found")
76-
}
77-
78-
func (m *mockBlockHeaderStore) WriteHeaders(headers ...headerfs.BlockHeader) error {
79-
for _, h := range headers {
80-
m.headers[h.BlockHash()] = *h.BlockHeader
81-
}
82-
83-
return nil
84-
}
3+
//
4+
//import (
5+
// "fmt"
6+
//
7+
// "github.com/btcsuite/btcd/blockchain"
8+
// "github.com/btcsuite/btcd/chaincfg/chainhash"
9+
// "github.com/btcsuite/btcd/wire"
10+
// "github.com/lightninglabs/neutrino/headerfs"
11+
//)
12+
//
13+
//// mockBlockHeaderStore is an implementation of the BlockHeaderStore backed by
14+
//// a simple map.
15+
//type mockBlockHeaderStore struct {
16+
// headers map[chainhash.Hash]wire.BlockHeader
17+
// heights map[uint32]wire.BlockHeader
18+
//}
19+
//
20+
//// A compile-time check to ensure the mockBlockHeaderStore adheres to the
21+
//// BlockHeaderStore interface.
22+
//var _ headerfs.BlockHeaderStore = (*mockBlockHeaderStore)(nil)
23+
//
24+
//// NewMockBlockHeaderStore returns a version of the BlockHeaderStore that's
25+
//// backed by an in-memory map. This instance is meant to be used by callers
26+
//// outside the package to unit test components that require a BlockHeaderStore
27+
//// interface.
28+
//func newMockBlockHeaderStore() *mockBlockHeaderStore {
29+
// return &mockBlockHeaderStore{
30+
// headers: make(map[chainhash.Hash]wire.BlockHeader),
31+
// heights: make(map[uint32]wire.BlockHeader),
32+
// }
33+
//}
34+
//
35+
//func (m *mockBlockHeaderStore) ChainTip() (*wire.BlockHeader,
36+
// uint32, error) {
37+
//
38+
// return nil, 0, nil
39+
//}
40+
//func (m *mockBlockHeaderStore) LatestBlockLocator() (
41+
// blockchain.BlockLocator, error) {
42+
//
43+
// return nil, nil
44+
//}
45+
//
46+
//func (m *mockBlockHeaderStore) FetchHeaderByHeight(height uint32) (
47+
// *wire.BlockHeader, error) {
48+
//
49+
// if header, ok := m.heights[height]; ok {
50+
// return &header, nil
51+
// }
52+
//
53+
// return nil, headerfs.ErrHeightNotFound
54+
//}
55+
//
56+
//func (m *mockBlockHeaderStore) FetchHeaderAncestors(uint32,
57+
// *chainhash.Hash) ([]wire.BlockHeader, uint32, error) {
58+
//
59+
// return nil, 0, nil
60+
//}
61+
//func (m *mockBlockHeaderStore) HeightFromHash(*chainhash.Hash) (uint32, error) {
62+
// return 0, nil
63+
//}
64+
//func (m *mockBlockHeaderStore) RollbackLastBlock() (*headerfs.BlockStamp,
65+
// error) {
66+
//
67+
// return nil, nil
68+
//}
69+
//
70+
//func (m *mockBlockHeaderStore) FetchHeader(h *chainhash.Hash) (
71+
// *wire.BlockHeader, uint32, error) {
72+
//
73+
// if header, ok := m.headers[*h]; ok {
74+
// return &header, 0, nil
75+
// }
76+
// return nil, 0, fmt.Errorf("not found")
77+
//}
78+
//
79+
//func (m *mockBlockHeaderStore) WriteHeaders(headers ...headerfs.BlockHeader) error {
80+
// for _, h := range headers {
81+
// m.headers[h.BlockHash()] = *h.BlockHeader
82+
// }
83+
//
84+
// return nil
85+
//}

neutrino.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,40 @@ func (sp *ServerPeer) SubscribeRecvMsg() (<-chan wire.Message, func()) {
532532
}
533533
}
534534

535+
// TODO: Unexport HeaderQuery
536+
func (sp *ServerPeer) QueryGetHeadersMsg(req interface{}) error {
537+
538+
queryGetHeaders, ok := req.(HeaderQuery)
539+
540+
if !ok {
541+
return errors.New("request is not type HeaderQuery")
542+
}
543+
err := sp.PushGetHeadersMsg(queryGetHeaders.Locator, queryGetHeaders.StopHash)
544+
545+
if err != nil {
546+
return err
547+
}
548+
549+
return nil
550+
}
551+
552+
func (sp *ServerPeer) IsPeerBehindStartHeight(req interface{}) bool {
553+
queryGetHeaders, ok := req.(*HeaderQuery)
554+
if !ok {
555+
log.Tracef("request is not type HeaderQuery")
556+
557+
return true
558+
}
559+
if sp.LastBlock() < queryGetHeaders.StartHeight {
560+
561+
return false
562+
563+
}
564+
565+
return true
566+
567+
}
568+
535569
// OnDisconnect returns a channel that will be closed when this peer is
536570
// disconnected.
537571
//
@@ -745,6 +779,7 @@ func NewChainService(cfg Config) (*ChainService, error) {
745779
ConnectedPeers: s.ConnectedPeers,
746780
NewWorker: query.NewWorker,
747781
Ranking: query.NewPeerRanking(),
782+
TestNewWorker: query.TestNewWorker,
748783
})
749784

750785
// We set the queryPeers method to point to queryChainServicePeers,

query/interface.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,24 @@ type Request struct {
112112
HandleResp func(req, resp wire.Message, peer string) Progress
113113
}
114114

115+
type TestRequest struct {
116+
// Req is the message request to send.
117+
Req interface{}
118+
119+
// HandleResp is a response handler that will be called for every
120+
// message received from the peer that the request was made to. It
121+
// should validate the response against the request made, and return a
122+
// Progress indicating whether the request was answered by this
123+
// particular response.
124+
//
125+
// NOTE: Since the worker's job queue will be stalled while this method
126+
// is running, it should not be doing any expensive operations. It
127+
// should validate the response and immediately return the progress.
128+
// The response should be handed off to another goroutine for
129+
// processing.
130+
HandleResp func(resp wire.Message, peer TestPeer) Progress
131+
}
132+
115133
// Dispatcher is an interface defining the API for dispatching queries to
116134
// bitcoin peers.
117135
type Dispatcher interface {
@@ -120,6 +138,7 @@ type Dispatcher interface {
120138
// batch of queries will be sent. Responses for the individual queries
121139
// should be handled by the response handler of each Request.
122140
Query(reqs []*Request, options ...QueryOption) chan error
141+
TestQuery(reqs []*TestRequest, options ...QueryOption) chan error
123142
}
124143

125144
// Peer is the interface that defines the methods needed by the query package
@@ -143,3 +162,27 @@ type Peer interface {
143162
// disconnected.
144163
OnDisconnect() <-chan struct{}
145164
}
165+
166+
type TestPeer interface {
167+
// QueueMessageWithEncoding adds the passed bitcoin message to the peer
168+
// send queue.
169+
QueueMessageWithEncoding(msg wire.Message, doneChan chan<- struct{},
170+
encoding wire.MessageEncoding)
171+
172+
// SubscribeRecvMsg adds a OnRead subscription to the peer. All bitcoin
173+
// messages received from this peer will be sent on the returned
174+
// channel. A closure is also returned, that should be called to cancel
175+
// the subscription.
176+
SubscribeRecvMsg() (<-chan wire.Message, func())
177+
178+
// Addr returns the address of this peer.
179+
Addr() string
180+
181+
// OnDisconnect returns a channel that will be closed when this peer is
182+
// disconnected.
183+
OnDisconnect() <-chan struct{}
184+
185+
QueryGetHeadersMsg(req interface{}) error
186+
187+
IsPeerBehindStartHeight(req interface{}) bool
188+
}

0 commit comments

Comments
 (0)