From 02ee5650c871e5ad05d42e91bfe7e026cc1b292a Mon Sep 17 00:00:00 2001 From: Valentine Wallace Date: Thu, 9 Aug 2018 00:05:28 -0700 Subject: [PATCH] chainntnfs/neutrino: add neutrino ChainConn implementation --- chainntnfs/neutrinonotify/neutrino.go | 43 +++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/chainntnfs/neutrinonotify/neutrino.go b/chainntnfs/neutrinonotify/neutrino.go index badda36b..da330dce 100644 --- a/chainntnfs/neutrinonotify/neutrino.go +++ b/chainntnfs/neutrinonotify/neutrino.go @@ -8,6 +8,7 @@ import ( "sync/atomic" "time" + "github.com/btcsuite/btcd/btcjson" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/rpcclient" "github.com/btcsuite/btcd/txscript" @@ -61,6 +62,8 @@ type NeutrinoNotifier struct { p2pNode *neutrino.ChainService chainView *neutrino.Rescan + chainConn *NeutrinoChainConn + notificationCancels chan interface{} notificationRegistry chan interface{} @@ -150,6 +153,8 @@ func (n *NeutrinoNotifier) Start() error { bestHeight, reorgSafetyLimit, ) + n.chainConn = &NeutrinoChainConn{n.p2pNode} + // Finally, we'll create our rescan struct, start it, and launch all // the goroutines we need to operate this ChainNotifier instance. n.chainView = n.p2pNode.NewRescan(rescanOptions...) @@ -877,3 +882,41 @@ func (n *NeutrinoNotifier) RegisterBlockEpochNtfn( }, nil } } + +// NeutrinoChainConn is a wrapper around neutrino's chain backend in order +// to satisfy the chainntnfs.ChainConn interface. +type NeutrinoChainConn struct { + p2pNode *neutrino.ChainService +} + +// GetBlockHeader returns the block header for a hash. +func (n *NeutrinoChainConn) GetBlockHeader(blockHash *chainhash.Hash) (*wire.BlockHeader, error) { + header, _, err := n.p2pNode.BlockHeaders.FetchHeader(blockHash) + if err != nil { + return nil, err + } + return header, nil +} + +// GetBlockHeaderVerbose returns a verbose block header result for a hash. This +// result only contains the height with a nil hash. +func (n *NeutrinoChainConn) GetBlockHeaderVerbose(blockHash *chainhash.Hash) ( + *btcjson.GetBlockHeaderVerboseResult, error) { + + _, height, err := n.p2pNode.BlockHeaders.FetchHeader(blockHash) + if err != nil { + return nil, err + } + // Since only the height is used from the result, leave the hash nil. + return &btcjson.GetBlockHeaderVerboseResult{Height: int32(height)}, nil +} + +// GetBlockHash returns the hash from a block height. +func (n *NeutrinoChainConn) GetBlockHash(blockHeight int64) (*chainhash.Hash, error) { + header, err := n.p2pNode.BlockHeaders.FetchHeaderByHeight(uint32(blockHeight)) + if err != nil { + return nil, err + } + hash := header.BlockHash() + return &hash, nil +}