[DEV-128] Fix BTCD sync (#65)

* [DEV-115] fix mistype mainCfg -> cfg in config/config.go

* [DEV-115] add config log

* [DEV-115] always handle block announcments

* [DEV-128] delete indexer tips bucket

* [DEV-128] disable cfilters by default

* [DEV-128] get rid of dbIndexDisconnectBlock and dbIndexConnectBlock

* [DEV-128] fix NTBlockConnected to send a block instead of TipHashes
This commit is contained in:
Ori Newman 2018-09-25 12:06:22 +03:00 committed by stasatdaglabs
parent 6dd3b815c1
commit 81453b221d
7 changed files with 12 additions and 126 deletions

View File

@ -553,7 +553,7 @@ func (dag *BlockDAG) connectBlock(node *blockNode, block *util.Block) error {
// The caller would typically want to react with actions such as
// updating wallets.
dag.dagLock.Unlock()
dag.sendNotification(NTBlockConnected, dag.virtual.TipHashes())
dag.sendNotification(NTBlockConnected, block)
dag.dagLock.Lock()
return nil

View File

@ -22,109 +22,6 @@ var (
indexTipsBucketName = []byte("idxtips")
)
// -----------------------------------------------------------------------------
// The index manager tracks the current tip of each index by using a parent
// bucket that contains an entry for index.
//
// The serialized format for an index tip is:
//
// [<block hash><block height>],...
//
// Field Type Size
// block hash daghash.Hash daghash.HashSize
// block height uint32 4 bytes
// -----------------------------------------------------------------------------
// dbPutIndexerTip uses an existing database transaction to update or add the
// current tip for the given index to the provided values.
func dbPutIndexerTip(dbTx database.Tx, idxKey []byte, hash *daghash.Hash, height int32) error {
serialized := make([]byte, daghash.HashSize+4)
copy(serialized, hash[:])
byteOrder.PutUint32(serialized[daghash.HashSize:], uint32(height))
indexesBucket := dbTx.Metadata().Bucket(indexTipsBucketName)
return indexesBucket.Put(idxKey, serialized)
}
// dbFetchIndexerTip uses an existing database transaction to retrieve the
// hash and height of the current tip for the provided index.
func dbFetchIndexerTip(dbTx database.Tx, idxKey []byte) (*daghash.Hash, int32, error) {
indexesBucket := dbTx.Metadata().Bucket(indexTipsBucketName)
serialized := indexesBucket.Get(idxKey)
if len(serialized) < daghash.HashSize+4 {
return nil, 0, database.Error{
ErrorCode: database.ErrCorruption,
Description: fmt.Sprintf("unexpected end of data for "+
"index %q tip", string(idxKey)),
}
}
var hash daghash.Hash
copy(hash[:], serialized[:daghash.HashSize])
height := int32(byteOrder.Uint32(serialized[daghash.HashSize:]))
return &hash, height, nil
}
// dbIndexConnectBlock adds all of the index entries associated with the
// given block using the provided indexer and updates the tip of the indexer
// accordingly. An error will be returned if the current tip for the indexer is
// not the previous block for the passed block.
func dbIndexConnectBlock(dbTx database.Tx, indexer Indexer, block *util.Block, virtual *blockdag.VirtualBlock) error {
// Assert that the block being connected properly connects to the
// current tip of the index.
idxKey := indexer.Key()
curTipHash, _, err := dbFetchIndexerTip(dbTx, idxKey)
if err != nil {
return err
}
header := block.MsgBlock().Header
if header.NumPrevBlocks > 0 && !curTipHash.IsEqual(header.SelectedPrevBlock()) {
return AssertError(fmt.Sprintf("dbIndexConnectBlock must be "+
"called with a block that extends the current index "+
"tip (%s, tip %s, block %s)", indexer.Name(),
curTipHash, block.Hash()))
}
// Notify the indexer with the connected block so it can index it.
if err := indexer.ConnectBlock(dbTx, block, virtual); err != nil {
return err
}
// Update the current index tip.
return dbPutIndexerTip(dbTx, idxKey, block.Hash(), block.Height())
}
// dbIndexDisconnectBlock removes all of the index entries associated with the
// given block using the provided indexer and updates the tip of the indexer
// accordingly. An error will be returned if the current tip for the indexer is
// not the passed block.
func dbIndexDisconnectBlock(dbTx database.Tx, indexer Indexer, block *util.Block, virtual *blockdag.VirtualBlock) error {
// Assert that the block being disconnected is the current tip of the
// index.
idxKey := indexer.Key()
curTipHash, _, err := dbFetchIndexerTip(dbTx, idxKey)
if err != nil {
return err
}
if !curTipHash.IsEqual(block.Hash()) {
return AssertError(fmt.Sprintf("dbIndexDisconnectBlock must "+
"be called with the block at the current index tip "+
"(%s, tip %s, block %s)", indexer.Name(),
curTipHash, block.Hash()))
}
// Notify the indexer with the disconnected block so it can remove all
// of the appropriate entries.
if err := indexer.DisconnectBlock(dbTx, block, virtual); err != nil {
return err
}
// Update the current index tip.
prevHash := block.MsgBlock().Header.SelectedPrevBlock()
return dbPutIndexerTip(dbTx, idxKey, prevHash, block.Height()-1)
}
// Manager defines an index manager that manages multiple optional indexes and
// implements the blockchain.IndexManager interface so it can be seamlessly
// plugged into normal chain processing.
@ -212,13 +109,6 @@ func (m *Manager) maybeCreateIndexes(dbTx database.Tx) error {
if err := indexer.Create(dbTx); err != nil {
return err
}
// Set the tip for the index to values which represent an
// uninitialized index.
err := dbPutIndexerTip(dbTx, idxKey, &daghash.Hash{}, -1)
if err != nil {
return err
}
}
return nil
@ -319,8 +209,8 @@ func (m *Manager) ConnectBlock(dbTx database.Tx, block *util.Block, virtual *blo
// Call each of the currently active optional indexes with the block
// being connected so they can update accordingly.
for _, index := range m.enabledIndexes {
err := dbIndexConnectBlock(dbTx, index, block, virtual)
if err != nil {
// Notify the indexer with the connected block so it can index it.
if err := index.ConnectBlock(dbTx, block, virtual); err != nil {
return err
}
}
@ -337,8 +227,9 @@ func (m *Manager) DisconnectBlock(dbTx database.Tx, block *util.Block, virtual *
// Call each of the currently active optional indexes with the block
// being disconnected so they can update accordingly.
for _, index := range m.enabledIndexes {
err := dbIndexDisconnectBlock(dbTx, index, block, virtual)
if err != nil {
// Notify the indexer with the disconnected block so it can remove all
// of the appropriate entries.
if err := index.DisconnectBlock(dbTx, block, virtual); err != nil {
return err
}
}

View File

@ -154,7 +154,7 @@ type configFlags struct {
BlockPrioritySize uint32 `long:"blockprioritysize" description:"Size in bytes for high-priority/low-fee transactions when creating a block"`
UserAgentComments []string `long:"uacomment" description:"Comment to add to the user agent -- See BIP 14 for more information."`
NoPeerBloomFilters bool `long:"nopeerbloomfilters" description:"Disable bloom filtering support"`
NoCFilters bool `long:"nocfilters" description:"Disable committed filtering (CF) support"`
EnableCFilters bool `long:"enablecfilters" description:"Enable committed filtering (CF) support"`
DropCfIndex bool `long:"dropcfindex" description:"Deletes the index used for committed filtering (CF) support from the database on start up and then exits."`
SigCacheMaxSize uint `long:"sigcachemaxsize" description:"The maximum number of entries in the signature verification cache"`
BlocksOnly bool `long:"blocksonly" description:"Do not accept transactions from remote peers."`

View File

@ -717,6 +717,7 @@ mempoolLoop:
var msgBlock wire.MsgBlock
msgBlock.Header = wire.BlockHeader{
Version: nextBlockVersion,
NumPrevBlocks: byte(len(virtualBlock.TipHashes())),
PrevBlocks: virtualBlock.TipHashes(),
MerkleRoot: *merkles[len(merkles)-1],
Timestamp: ts,

View File

@ -922,12 +922,6 @@ func (sm *SyncManager) handleInvMsg(imsg *invMsg) {
peer.UpdateLastAnnouncedBlock(&invVects[lastBlock].Hash)
}
// Ignore invs from peers that aren't the sync if we are not current.
// Helps prevent fetching a mass of orphans.
if peer != sm.syncPeer && !sm.current() {
return
}
// If our chain is current and a peer announces a block we already
// know of, then update their current block height.
if lastBlock != -1 && sm.current() {

View File

@ -167,8 +167,8 @@
; Must not include characters '/', ':', '(' and ')'.
; uacomment=
; Disable committed peer filtering (CF).
; nocfilters=1
; Enable committed peer filtering (CF).
; enablecfilters=1
; ------------------------------------------------------------------------------
; RPC server options - The following options control the built-in RPC server

View File

@ -2296,7 +2296,7 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params
if config.MainConfig().NoPeerBloomFilters {
services &^= wire.SFNodeBloom
}
if config.MainConfig().NoCFilters {
if !config.MainConfig().EnableCFilters {
services &^= wire.SFNodeCF
}
@ -2362,7 +2362,7 @@ func NewServer(listenAddrs []string, db database.DB, dagParams *dagconfig.Params
s.AddrIndex = indexers.NewAddrIndex(db, dagParams)
indexes = append(indexes, s.AddrIndex)
}
if !config.MainConfig().NoCFilters {
if config.MainConfig().EnableCFilters {
indxLog.Info("cf index is enabled")
s.CfIndex = indexers.NewCfIndex(db, dagParams)
indexes = append(indexes, s.CfIndex)