mirror of
https://github.com/FlipsideCrypto/dcrd.git
synced 2026-02-06 10:56:47 +00:00
multi: decouple BlockManager from server.
This adds a blockManager config and removes direct references to the server from the blockManager.
This commit is contained in:
parent
6a3c1fea49
commit
6968dcfdbd
215
blockmanager.go
215
blockmanager.go
@ -22,6 +22,7 @@ import (
|
||||
"github.com/decred/dcrd/chaincfg/chainhash"
|
||||
"github.com/decred/dcrd/database"
|
||||
"github.com/decred/dcrd/dcrutil"
|
||||
"github.com/decred/dcrd/fees"
|
||||
"github.com/decred/dcrd/mempool/v2"
|
||||
"github.com/decred/dcrd/wire"
|
||||
)
|
||||
@ -292,10 +293,51 @@ type headerNode struct {
|
||||
hash *chainhash.Hash
|
||||
}
|
||||
|
||||
// PeerNotifier provides an interface for server peer notifications.
|
||||
type PeerNotifier interface {
|
||||
// AnnounceNewTransactions generates and relays inventory vectors and
|
||||
// notifies both websocket and getblocktemplate long poll clients of
|
||||
// the passed transactions.
|
||||
AnnounceNewTransactions(txns []*dcrutil.Tx)
|
||||
|
||||
// UpdatePeerHeights updates the heights of all peers who have have
|
||||
// announced the latest connected main chain block, or a recognized orphan.
|
||||
UpdatePeerHeights(latestBlkHash *chainhash.Hash, latestHeight int64, updateSource *serverPeer)
|
||||
|
||||
// RelayInventory relays the passed inventory vector to all connected peers
|
||||
// that are not already known to have it.
|
||||
RelayInventory(invVect *wire.InvVect, data interface{}, immediate bool)
|
||||
|
||||
// TransactionConfirmed marks the provided single confirmation transaction
|
||||
// as no longer needing rebroadcasting.
|
||||
TransactionConfirmed(tx *dcrutil.Tx)
|
||||
}
|
||||
|
||||
// blockManangerConfig is a configuration struct for a blockManager.
|
||||
type blockManagerConfig struct {
|
||||
PeerNotifier PeerNotifier
|
||||
TimeSource blockchain.MedianTimeSource
|
||||
|
||||
// The following fields are for accessing the chain and its configuration.
|
||||
Chain *blockchain.BlockChain
|
||||
ChainParams *chaincfg.Params
|
||||
|
||||
// The following fields provide access to the fee estimator, mempool and
|
||||
// the background block template generator.
|
||||
FeeEstimator *fees.Estimator
|
||||
TxMemPool *mempool.TxPool
|
||||
BgBlkTmplGenerator *BgBlkTmplGenerator
|
||||
|
||||
// The following fields are blockManger callbacks.
|
||||
NotifyWinningTickets func(*WinningTicketsNtfnData)
|
||||
PruneRebroadcastInventory func()
|
||||
RpcServer func() *rpcServer
|
||||
}
|
||||
|
||||
// blockManager provides a concurrency safe block manager for handling all
|
||||
// incoming blocks.
|
||||
type blockManager struct {
|
||||
server *server
|
||||
cfg *blockManagerConfig
|
||||
started int32
|
||||
shutdown int32
|
||||
chain *blockchain.BlockChain
|
||||
@ -368,7 +410,7 @@ func (b *blockManager) findNextHeaderCheckpoint(height int64) *chaincfg.Checkpoi
|
||||
if cfg.DisableCheckpoints {
|
||||
return nil
|
||||
}
|
||||
checkpoints := b.server.chainParams.Checkpoints
|
||||
checkpoints := b.chain.Checkpoints()
|
||||
if len(checkpoints) == 0 {
|
||||
return nil
|
||||
}
|
||||
@ -613,7 +655,7 @@ func (b *blockManager) handleTxMsg(tmsg *txMsg) {
|
||||
// Process the transaction to include validation, insertion in the
|
||||
// memory pool, orphan handling, etc.
|
||||
allowOrphans := cfg.MaxOrphanTxs > 0
|
||||
acceptedTxs, err := b.server.txMemPool.ProcessTransaction(tmsg.tx,
|
||||
acceptedTxs, err := b.cfg.TxMemPool.ProcessTransaction(tmsg.tx,
|
||||
allowOrphans, true, true)
|
||||
|
||||
// Remove transaction from request maps. Either the mempool/chain
|
||||
@ -649,7 +691,7 @@ func (b *blockManager) handleTxMsg(tmsg *txMsg) {
|
||||
return
|
||||
}
|
||||
|
||||
b.server.AnnounceNewTransactions(acceptedTxs)
|
||||
b.cfg.PeerNotifier.AnnounceNewTransactions(acceptedTxs)
|
||||
}
|
||||
|
||||
// current returns true if we believe we are synced with our peers, false if we
|
||||
@ -732,7 +774,7 @@ func (b *blockManager) checkBlockForHiddenVotes(block *dcrutil.Block) {
|
||||
var oldTickets []*dcrutil.Tx
|
||||
var oldRevocations []*dcrutil.Tx
|
||||
oldVoteMap := make(map[chainhash.Hash]struct{},
|
||||
int(b.server.chainParams.TicketsPerBlock))
|
||||
int(b.cfg.ChainParams.TicketsPerBlock))
|
||||
templateBlock := dcrutil.NewBlock(template.Block)
|
||||
|
||||
// Add all the votes found in our template. Keep their
|
||||
@ -768,12 +810,11 @@ func (b *blockManager) checkBlockForHiddenVotes(block *dcrutil.Block) {
|
||||
// Check the length of the reconstructed voter list for
|
||||
// integrity.
|
||||
votesTotal := len(newVotes)
|
||||
if votesTotal > int(b.server.chainParams.TicketsPerBlock) {
|
||||
if votesTotal > int(b.cfg.ChainParams.TicketsPerBlock) {
|
||||
bmgrLog.Warnf("error found while adding hidden votes "+
|
||||
"from block %v to the old block template: %v max "+
|
||||
"votes expected but %v votes found", block.Hash(),
|
||||
int(b.server.chainParams.TicketsPerBlock),
|
||||
votesTotal)
|
||||
int(b.cfg.ChainParams.TicketsPerBlock), votesTotal)
|
||||
return
|
||||
}
|
||||
|
||||
@ -816,11 +857,9 @@ func (b *blockManager) checkBlockForHiddenVotes(block *dcrutil.Block) {
|
||||
}
|
||||
coinbase, err := createCoinbaseTx(b.chain.FetchSubsidyCache(),
|
||||
template.Block.Transactions[0].TxIn[0].SignatureScript,
|
||||
opReturnPkScript,
|
||||
int64(template.Block.Header.Height),
|
||||
opReturnPkScript, int64(template.Block.Header.Height),
|
||||
cfg.miningAddrs[rand.Intn(len(cfg.miningAddrs))],
|
||||
uint16(votesTotal),
|
||||
b.server.chainParams)
|
||||
uint16(votesTotal), b.cfg.ChainParams)
|
||||
if err != nil {
|
||||
bmgrLog.Errorf("failed to create coinbase while generating " +
|
||||
"block with extra found voters")
|
||||
@ -966,7 +1005,7 @@ func (b *blockManager) handleBlockMsg(bmsg *blockMsg) {
|
||||
// votes in it that were hidden from the network and which
|
||||
// validate our parent block. We should bolt these new votes
|
||||
// into the tx tree stake of the old block template on parent.
|
||||
svl := b.server.chainParams.StakeValidationHeight
|
||||
svl := b.cfg.ChainParams.StakeValidationHeight
|
||||
if b.AggressiveMining && bmsg.block.Height() >= svl {
|
||||
b.checkBlockForHiddenVotes(bmsg.block)
|
||||
}
|
||||
@ -974,7 +1013,7 @@ func (b *blockManager) handleBlockMsg(bmsg *blockMsg) {
|
||||
// Notify stake difficulty subscribers and prune invalidated
|
||||
// transactions.
|
||||
best := b.chain.BestSnapshot()
|
||||
r := b.server.rpcServer
|
||||
r := b.cfg.RpcServer()
|
||||
if r != nil {
|
||||
// Update registered websocket clients on the
|
||||
// current stake difficulty.
|
||||
@ -985,9 +1024,8 @@ func (b *blockManager) handleBlockMsg(bmsg *blockMsg) {
|
||||
best.NextStakeDiff,
|
||||
})
|
||||
}
|
||||
b.server.txMemPool.PruneStakeTx(best.NextStakeDiff,
|
||||
best.Height)
|
||||
b.server.txMemPool.PruneExpiredTx()
|
||||
b.cfg.TxMemPool.PruneStakeTx(best.NextStakeDiff, best.Height)
|
||||
b.cfg.TxMemPool.PruneExpiredTx()
|
||||
|
||||
// Update this peer's latest block height, for future
|
||||
// potential sync node candidancy.
|
||||
@ -1000,9 +1038,8 @@ func (b *blockManager) handleBlockMsg(bmsg *blockMsg) {
|
||||
// Allow any clients performing long polling via the
|
||||
// getblocktemplate RPC to be notified when the new block causes
|
||||
// their old block template to become stale.
|
||||
rpcServer := b.server.rpcServer
|
||||
if rpcServer != nil {
|
||||
rpcServer.gbtWorkState.NotifyBlockConnected(blockHash)
|
||||
if r := b.cfg.RpcServer(); r != nil {
|
||||
r.gbtWorkState.NotifyBlockConnected(blockHash)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1014,7 +1051,7 @@ func (b *blockManager) handleBlockMsg(bmsg *blockMsg) {
|
||||
if blkHashUpdate != nil && heightUpdate != 0 {
|
||||
bmsg.peer.UpdateLastBlockHeight(heightUpdate)
|
||||
if isOrphan || b.current() {
|
||||
go b.server.UpdatePeerHeights(blkHashUpdate, heightUpdate,
|
||||
go b.cfg.PeerNotifier.UpdatePeerHeights(blkHashUpdate, heightUpdate,
|
||||
bmsg.peer)
|
||||
}
|
||||
}
|
||||
@ -1235,7 +1272,7 @@ func (b *blockManager) haveInventory(invVect *wire.InvVect) (bool, error) {
|
||||
case wire.InvTypeTx:
|
||||
// Ask the transaction memory pool if the transaction is known
|
||||
// to it in any form (main pool or orphan).
|
||||
if b.server.txMemPool.HaveTransaction(&invVect.Hash) {
|
||||
if b.cfg.TxMemPool.HaveTransaction(&invVect.Hash) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@ -1290,7 +1327,6 @@ func (b *blockManager) handleInvMsg(imsg *invMsg) {
|
||||
if lastBlock != -1 && isCurrent {
|
||||
blkHeight, err := b.chain.BlockHeightByHash(&invVects[lastBlock].Hash)
|
||||
if err == nil {
|
||||
|
||||
imsg.peer.UpdateLastBlockHeight(blkHeight)
|
||||
}
|
||||
}
|
||||
@ -1515,7 +1551,7 @@ out:
|
||||
// Notify stake difficulty subscribers and prune
|
||||
// invalidated transactions.
|
||||
best := b.chain.BestSnapshot()
|
||||
r := b.server.rpcServer
|
||||
r := b.cfg.RpcServer()
|
||||
if r != nil {
|
||||
r.ntfnMgr.NotifyStakeDifficulty(
|
||||
&StakeDifficultyNtfnData{
|
||||
@ -1524,9 +1560,9 @@ out:
|
||||
best.NextStakeDiff,
|
||||
})
|
||||
}
|
||||
b.server.txMemPool.PruneStakeTx(best.NextStakeDiff,
|
||||
b.cfg.TxMemPool.PruneStakeTx(best.NextStakeDiff,
|
||||
best.Height)
|
||||
b.server.txMemPool.PruneExpiredTx()
|
||||
b.cfg.TxMemPool.PruneExpiredTx()
|
||||
}
|
||||
|
||||
msg.reply <- forceReorganizationResponse{
|
||||
@ -1552,12 +1588,12 @@ out:
|
||||
continue
|
||||
}
|
||||
|
||||
r := b.cfg.RpcServer()
|
||||
onMainChain := !isOrphan && forkLen == 0
|
||||
if onMainChain {
|
||||
// Notify stake difficulty subscribers and prune
|
||||
// invalidated transactions.
|
||||
best := b.chain.BestSnapshot()
|
||||
r := b.server.rpcServer
|
||||
if r != nil {
|
||||
r.ntfnMgr.NotifyStakeDifficulty(
|
||||
&StakeDifficultyNtfnData{
|
||||
@ -1566,17 +1602,16 @@ out:
|
||||
best.NextStakeDiff,
|
||||
})
|
||||
}
|
||||
b.server.txMemPool.PruneStakeTx(best.NextStakeDiff,
|
||||
b.cfg.TxMemPool.PruneStakeTx(best.NextStakeDiff,
|
||||
best.Height)
|
||||
b.server.txMemPool.PruneExpiredTx()
|
||||
b.cfg.TxMemPool.PruneExpiredTx()
|
||||
}
|
||||
|
||||
// Allow any clients performing long polling via the
|
||||
// getblocktemplate RPC to be notified when the new block causes
|
||||
// their old block template to become stale.
|
||||
rpcServer := b.server.rpcServer
|
||||
if rpcServer != nil {
|
||||
rpcServer.gbtWorkState.NotifyBlockConnected(msg.block.Hash())
|
||||
if r != nil {
|
||||
r.gbtWorkState.NotifyBlockConnected(msg.block.Hash())
|
||||
}
|
||||
|
||||
msg.reply <- processBlockResponse{
|
||||
@ -1585,7 +1620,7 @@ out:
|
||||
}
|
||||
|
||||
case processTransactionMsg:
|
||||
acceptedTxs, err := b.server.txMemPool.ProcessTransaction(msg.tx,
|
||||
acceptedTxs, err := b.cfg.TxMemPool.ProcessTransaction(msg.tx,
|
||||
msg.allowOrphans, msg.rateLimit, msg.allowHighFees)
|
||||
msg.reply <- processTransactionResponse{
|
||||
acceptedTxs: acceptedTxs,
|
||||
@ -1616,8 +1651,7 @@ out:
|
||||
msg.reply <- setParentTemplateResponse{}
|
||||
|
||||
default:
|
||||
bmgrLog.Warnf("Invalid message type in block "+
|
||||
"handler: %T", msg)
|
||||
bmgrLog.Warnf("Invalid message type in block handler: %T", msg)
|
||||
}
|
||||
|
||||
case <-b.quit:
|
||||
@ -1667,9 +1701,10 @@ func isDoubleSpendOrDuplicateError(err error) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// handleNotifyMsg handles notifications from blockchain. It does things such
|
||||
// as request orphan block parents and relay accepted blocks to connected peers.
|
||||
func (b *blockManager) handleNotifyMsg(notification *blockchain.Notification) {
|
||||
// handleBlockchainNotification handles notifications from blockchain. It does
|
||||
// things such as request orphan block parents and relay accepted blocks to
|
||||
// connected peers.
|
||||
func (b *blockManager) handleBlockchainNotification(notification *blockchain.Notification) {
|
||||
switch notification.Type {
|
||||
// A block that intends to extend the main chain has passed all sanity and
|
||||
// contextual checks and the chain is believed to be current. Relay it to
|
||||
@ -1686,7 +1721,7 @@ func (b *blockManager) handleNotifyMsg(notification *blockchain.Notification) {
|
||||
|
||||
// Generate the inventory vector and relay it immediately.
|
||||
iv := wire.NewInvVect(wire.InvTypeBlock, block.Hash())
|
||||
b.server.RelayInventory(iv, block.MsgBlock().Header, true)
|
||||
b.cfg.PeerNotifier.RelayInventory(iv, block.MsgBlock().Header, true)
|
||||
b.announcedBlockMtx.Lock()
|
||||
b.announcedBlock = block.Hash()
|
||||
b.announcedBlockMtx.Unlock()
|
||||
@ -1738,10 +1773,10 @@ func (b *blockManager) handleNotifyMsg(notification *blockchain.Notification) {
|
||||
bestHeight := band.BestHeight
|
||||
blockHeight := int64(block.MsgBlock().Header.Height)
|
||||
reorgDepth := bestHeight - (blockHeight - band.ForkLen)
|
||||
if b.server.rpcServer != nil &&
|
||||
blockHeight >= b.server.chainParams.StakeValidationHeight-1 &&
|
||||
if b.cfg.RpcServer() != nil &&
|
||||
blockHeight >= b.cfg.ChainParams.StakeValidationHeight-1 &&
|
||||
reorgDepth < maxReorgDepthNotify &&
|
||||
blockHeight > b.server.chainParams.LatestCheckpointHeight() &&
|
||||
blockHeight > b.cfg.ChainParams.LatestCheckpointHeight() &&
|
||||
!b.notifiedWinningTickets(blockHash) {
|
||||
|
||||
// Obtain the winning tickets for this block. handleNotifyMsg
|
||||
@ -1752,15 +1787,14 @@ func (b *blockManager) handleNotifyMsg(notification *blockchain.Notification) {
|
||||
bmgrLog.Errorf("Couldn't calculate winning tickets for "+
|
||||
"accepted block %v: %v", blockHash, err.Error())
|
||||
} else {
|
||||
ntfnData := &WinningTicketsNtfnData{
|
||||
// Notify registered websocket clients of newly
|
||||
// eligible tickets to vote on.
|
||||
b.cfg.NotifyWinningTickets(&WinningTicketsNtfnData{
|
||||
BlockHash: *blockHash,
|
||||
BlockHeight: blockHeight,
|
||||
Tickets: wt,
|
||||
}
|
||||
})
|
||||
|
||||
// Notify registered websocket clients of newly
|
||||
// eligible tickets to vote on.
|
||||
b.server.rpcServer.ntfnMgr.NotifyWinningTickets(ntfnData)
|
||||
b.lotteryDataBroadcastMutex.Lock()
|
||||
b.lotteryDataBroadcast[*blockHash] = struct{}{}
|
||||
b.lotteryDataBroadcastMutex.Unlock()
|
||||
@ -1775,32 +1809,32 @@ func (b *blockManager) handleNotifyMsg(notification *blockchain.Notification) {
|
||||
b.announcedBlockMtx.Unlock()
|
||||
if !sent {
|
||||
iv := wire.NewInvVect(wire.InvTypeBlock, blockHash)
|
||||
b.server.RelayInventory(iv, block.MsgBlock().Header, true)
|
||||
b.cfg.PeerNotifier.RelayInventory(iv, block.MsgBlock().Header, true)
|
||||
}
|
||||
|
||||
// Inform the background block template generator about the accepted
|
||||
// block.
|
||||
if b.server.bg != nil {
|
||||
b.server.bg.BlockAccepted(block)
|
||||
if b.cfg.BgBlkTmplGenerator != nil {
|
||||
b.cfg.BgBlkTmplGenerator.BlockAccepted(block)
|
||||
}
|
||||
|
||||
if !b.server.feeEstimator.IsEnabled() {
|
||||
if !b.cfg.FeeEstimator.IsEnabled() {
|
||||
// fee estimation can only start after we have performed an initial
|
||||
// sync, otherwise we'll start adding mempool transactions at the
|
||||
// wrong height.
|
||||
b.server.feeEstimator.Enable(block.Height())
|
||||
b.cfg.FeeEstimator.Enable(block.Height())
|
||||
}
|
||||
|
||||
// A block has been connected to the main block chain.
|
||||
case blockchain.NTBlockConnected:
|
||||
blockSlice, ok := notification.Data.([]*dcrutil.Block)
|
||||
if !ok {
|
||||
bmgrLog.Warnf("Chain connected notification is not a block slice.")
|
||||
bmgrLog.Warnf("Block connected notification is not a block slice.")
|
||||
break
|
||||
}
|
||||
|
||||
if len(blockSlice) != 2 {
|
||||
bmgrLog.Warnf("Chain connected notification is wrong size slice.")
|
||||
bmgrLog.Warnf("Block connected notification is wrong size slice.")
|
||||
break
|
||||
}
|
||||
|
||||
@ -1811,7 +1845,7 @@ func (b *blockManager) handleNotifyMsg(notification *blockchain.Notification) {
|
||||
// estimation. This must be done before attempting to remove
|
||||
// transactions from the mempool because the mempool will alert the
|
||||
// estimator of the txs that are leaving
|
||||
b.server.feeEstimator.ProcessBlock(block)
|
||||
b.cfg.FeeEstimator.ProcessBlock(block)
|
||||
|
||||
// TODO: In the case the new tip disapproves the previous block, any
|
||||
// transactions the previous block contains in its regular tree which
|
||||
@ -1837,22 +1871,19 @@ func (b *blockManager) handleNotifyMsg(notification *blockchain.Notification) {
|
||||
//
|
||||
// Also, in the case the RPC server is enabled, stop rebroadcasting any
|
||||
// transactions in the block that were setup to be rebroadcast.
|
||||
txMemPool := b.server.txMemPool
|
||||
txMemPool := b.cfg.TxMemPool
|
||||
handleConnectedBlockTxns := func(txns []*dcrutil.Tx) {
|
||||
for _, tx := range txns {
|
||||
txMemPool.RemoveTransaction(tx, false)
|
||||
txMemPool.RemoveDoubleSpends(tx)
|
||||
txMemPool.RemoveOrphan(tx)
|
||||
acceptedTxs := txMemPool.ProcessOrphans(tx)
|
||||
b.server.AnnounceNewTransactions(acceptedTxs)
|
||||
b.cfg.PeerNotifier.AnnounceNewTransactions(acceptedTxs)
|
||||
|
||||
// Now that this block is in the blockchain, mark the
|
||||
// transaction (except the coinbase) as no longer needing
|
||||
// rebroadcasting.
|
||||
if b.server.rpcServer != nil {
|
||||
iv := wire.NewInvVect(wire.InvTypeTx, tx.Hash())
|
||||
b.server.RemoveRebroadcastInventory(iv)
|
||||
}
|
||||
b.cfg.PeerNotifier.TransactionConfirmed(tx)
|
||||
}
|
||||
}
|
||||
handleConnectedBlockTxns(block.Transactions()[1:])
|
||||
@ -1887,16 +1918,16 @@ func (b *blockManager) handleNotifyMsg(notification *blockchain.Notification) {
|
||||
}
|
||||
}
|
||||
|
||||
if r := b.server.rpcServer; r != nil {
|
||||
if r := b.cfg.RpcServer(); r != nil {
|
||||
// Filter and update the rebroadcast inventory.
|
||||
b.server.PruneRebroadcastInventory()
|
||||
b.cfg.PruneRebroadcastInventory()
|
||||
|
||||
// Notify registered websocket clients of incoming block.
|
||||
r.ntfnMgr.NotifyBlockConnected(block)
|
||||
}
|
||||
|
||||
if b.server.bg != nil {
|
||||
b.server.bg.BlockConnected(block)
|
||||
if b.cfg.BgBlkTmplGenerator != nil {
|
||||
b.cfg.BgBlkTmplGenerator.BlockConnected(block)
|
||||
}
|
||||
|
||||
// Stake tickets are spent or missed from the most recently connected block.
|
||||
@ -1908,7 +1939,7 @@ func (b *blockManager) handleNotifyMsg(notification *blockchain.Notification) {
|
||||
break
|
||||
}
|
||||
|
||||
if r := b.server.rpcServer; r != nil {
|
||||
if r := b.cfg.RpcServer(); r != nil {
|
||||
r.ntfnMgr.NotifySpentAndMissedTickets(tnd)
|
||||
}
|
||||
|
||||
@ -1921,7 +1952,7 @@ func (b *blockManager) handleNotifyMsg(notification *blockchain.Notification) {
|
||||
break
|
||||
}
|
||||
|
||||
if r := b.server.rpcServer; r != nil {
|
||||
if r := b.cfg.RpcServer(); r != nil {
|
||||
r.ntfnMgr.NotifyNewTickets(tnd)
|
||||
}
|
||||
|
||||
@ -1929,12 +1960,12 @@ func (b *blockManager) handleNotifyMsg(notification *blockchain.Notification) {
|
||||
case blockchain.NTBlockDisconnected:
|
||||
blockSlice, ok := notification.Data.([]*dcrutil.Block)
|
||||
if !ok {
|
||||
bmgrLog.Warnf("Chain disconnected notification is not a block slice.")
|
||||
bmgrLog.Warnf("Block disconnected notification is not a block slice.")
|
||||
break
|
||||
}
|
||||
|
||||
if len(blockSlice) != 2 {
|
||||
bmgrLog.Warnf("Chain disconnected notification is wrong size slice.")
|
||||
bmgrLog.Warnf("Block disconnected notification is wrong size slice.")
|
||||
break
|
||||
}
|
||||
|
||||
@ -1947,7 +1978,7 @@ func (b *blockManager) handleNotifyMsg(notification *blockchain.Notification) {
|
||||
// transactions and any that are now double spends from the transaction
|
||||
// pool. Transactions which depend on a confirmed transaction are NOT
|
||||
// removed recursively because they are still valid.
|
||||
txMemPool := b.server.txMemPool
|
||||
txMemPool := b.cfg.TxMemPool
|
||||
if !headerApprovesParent(&block.MsgBlock().Header) {
|
||||
for _, tx := range parentBlock.Transactions()[1:] {
|
||||
txMemPool.RemoveTransaction(tx, false)
|
||||
@ -1990,17 +2021,14 @@ func (b *blockManager) handleNotifyMsg(notification *blockchain.Notification) {
|
||||
handleDisconnectedBlockTxns(block.Transactions()[1:])
|
||||
handleDisconnectedBlockTxns(block.STransactions())
|
||||
|
||||
if b.server.bg != nil {
|
||||
b.server.bg.BlockDisconnected(block)
|
||||
if b.cfg.BgBlkTmplGenerator != nil {
|
||||
b.cfg.BgBlkTmplGenerator.BlockDisconnected(block)
|
||||
}
|
||||
|
||||
// Filter and update the rebroadcast inventory.
|
||||
b.server.PruneRebroadcastInventory()
|
||||
|
||||
// Notify registered websocket clients.
|
||||
if r := b.server.rpcServer; r != nil {
|
||||
if r := b.cfg.RpcServer(); r != nil {
|
||||
// Filter and update the rebroadcast inventory.
|
||||
b.server.PruneRebroadcastInventory()
|
||||
b.cfg.PruneRebroadcastInventory()
|
||||
|
||||
// Notify registered websocket clients.
|
||||
r.ntfnMgr.NotifyBlockDisconnected(block)
|
||||
@ -2008,14 +2036,14 @@ func (b *blockManager) handleNotifyMsg(notification *blockchain.Notification) {
|
||||
|
||||
// Chain reorganization has commenced.
|
||||
case blockchain.NTChainReorgStarted:
|
||||
if b.server.bg != nil {
|
||||
b.server.bg.ChainReorgStarted()
|
||||
if b.cfg.BgBlkTmplGenerator != nil {
|
||||
b.cfg.BgBlkTmplGenerator.ChainReorgStarted()
|
||||
}
|
||||
|
||||
// Chain reorganization has concluded.
|
||||
case blockchain.NTChainReorgDone:
|
||||
if b.server.bg != nil {
|
||||
b.server.bg.ChainReorgDone()
|
||||
if b.cfg.BgBlkTmplGenerator != nil {
|
||||
b.cfg.BgBlkTmplGenerator.ChainReorgDone()
|
||||
}
|
||||
|
||||
// The blockchain is reorganizing.
|
||||
@ -2027,7 +2055,7 @@ func (b *blockManager) handleNotifyMsg(notification *blockchain.Notification) {
|
||||
}
|
||||
|
||||
// Notify registered websocket clients.
|
||||
if r := b.server.rpcServer; r != nil {
|
||||
if r := b.cfg.RpcServer(); r != nil {
|
||||
r.ntfnMgr.NotifyReorganization(rd)
|
||||
}
|
||||
|
||||
@ -2194,7 +2222,7 @@ func (b *blockManager) requestFromPeer(p *serverPeer, blocks, txs []*chainhash.H
|
||||
|
||||
// Ask the transaction memory pool if the transaction is known
|
||||
// to it in any form (main pool or orphan).
|
||||
if b.server.txMemPool.HaveTransaction(vh) {
|
||||
if b.cfg.TxMemPool.HaveTransaction(vh) {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -2357,9 +2385,10 @@ func (b *blockManager) SetParentTemplate(bt *BlockTemplate) {
|
||||
|
||||
// newBlockManager returns a new Decred block manager.
|
||||
// Use Start to begin processing asynchronous block and inv updates.
|
||||
func newBlockManager(s *server, indexManager blockchain.IndexManager, interrupt <-chan struct{}) (*blockManager, error) {
|
||||
func newBlockManager(config *blockManagerConfig) (*blockManager, error) {
|
||||
bm := blockManager{
|
||||
server: s,
|
||||
cfg: config,
|
||||
chain: config.Chain,
|
||||
rejectedTxns: make(map[chainhash.Hash]struct{}),
|
||||
requestedTxns: make(map[chainhash.Hash]struct{}),
|
||||
requestedBlocks: make(map[chainhash.Hash]struct{}),
|
||||
@ -2370,20 +2399,6 @@ func newBlockManager(s *server, indexManager blockchain.IndexManager, interrupt
|
||||
quit: make(chan struct{}),
|
||||
}
|
||||
|
||||
// Create a new block chain instance with the appropriate configuration.
|
||||
var err error
|
||||
bm.chain, err = blockchain.New(&blockchain.Config{
|
||||
DB: s.db,
|
||||
Interrupt: interrupt,
|
||||
ChainParams: s.chainParams,
|
||||
TimeSource: s.timeSource,
|
||||
Notifications: bm.handleNotifyMsg,
|
||||
SigCache: s.sigCache,
|
||||
IndexManager: indexManager,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
best := bm.chain.BestSnapshot()
|
||||
bm.chain.DisableCheckpoints(cfg.DisableCheckpoints)
|
||||
if !cfg.DisableCheckpoints {
|
||||
@ -2398,7 +2413,7 @@ func newBlockManager(s *server, indexManager blockchain.IndexManager, interrupt
|
||||
|
||||
// Dump the blockchain here if asked for it, and quit.
|
||||
if cfg.DumpBlockchain != "" {
|
||||
err = dumpBlockChain(bm.chain, best.Height)
|
||||
err := dumpBlockChain(bm.chain, best.Height)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
18
mining.go
18
mining.go
@ -776,8 +776,8 @@ func deepCopyBlockTemplate(blockTemplate *BlockTemplate) *BlockTemplate {
|
||||
// miner.
|
||||
// Safe for concurrent access.
|
||||
func handleTooFewVoters(subsidyCache *blockchain.SubsidyCache, nextHeight int64, miningAddress dcrutil.Address, bm *blockManager) (*BlockTemplate, error) {
|
||||
timeSource := bm.server.timeSource
|
||||
stakeValidationHeight := bm.server.chainParams.StakeValidationHeight
|
||||
timeSource := bm.cfg.TimeSource
|
||||
stakeValidationHeight := bm.cfg.ChainParams.StakeValidationHeight
|
||||
curTemplate := bm.GetCurrentTemplate()
|
||||
|
||||
// Check to see if we've fallen off the chain, for example if a
|
||||
@ -807,7 +807,7 @@ func handleTooFewVoters(subsidyCache *blockchain.SubsidyCache, nextHeight int64,
|
||||
|
||||
// If we're on testnet, the time since this last block
|
||||
// listed as the parent must be taken into consideration.
|
||||
if bm.server.chainParams.ReduceMinDifficulty {
|
||||
if bm.cfg.ChainParams.ReduceMinDifficulty {
|
||||
parentHash := cptCopy.Block.Header.PrevBlock
|
||||
|
||||
requiredDifficulty, err :=
|
||||
@ -876,13 +876,9 @@ func handleTooFewVoters(subsidyCache *blockchain.SubsidyCache, nextHeight int64,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
coinbaseTx, err := createCoinbaseTx(subsidyCache,
|
||||
coinbaseScript,
|
||||
opReturnPkScript,
|
||||
topBlock.Height(),
|
||||
miningAddress,
|
||||
topBlock.MsgBlock().Header.Voters,
|
||||
bm.server.chainParams)
|
||||
coinbaseTx, err := createCoinbaseTx(subsidyCache, coinbaseScript,
|
||||
opReturnPkScript, topBlock.Height(), miningAddress,
|
||||
topBlock.MsgBlock().Header.Voters, bm.cfg.ChainParams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -901,7 +897,7 @@ func handleTooFewVoters(subsidyCache *blockchain.SubsidyCache, nextHeight int64,
|
||||
|
||||
// If we're on testnet, the time since this last block
|
||||
// listed as the parent must be taken into consideration.
|
||||
if bm.server.chainParams.ReduceMinDifficulty {
|
||||
if bm.cfg.ChainParams.ReduceMinDifficulty {
|
||||
parentHash := topBlock.MsgBlock().Header.PrevBlock
|
||||
|
||||
requiredDifficulty, err :=
|
||||
|
||||
58
rpcserver.go
58
rpcserver.go
@ -1392,7 +1392,7 @@ func handleEstimateStakeDiff(s *rpcServer, cmd interface{}, closeChan <-chan str
|
||||
c := cmd.(*dcrjson.EstimateStakeDiffCmd)
|
||||
|
||||
// Minimum possible stake difficulty.
|
||||
chain := s.server.blockManager.chain
|
||||
chain := s.server.chain
|
||||
min, err := chain.EstimateNextStakeDifficulty(0, false)
|
||||
if err != nil {
|
||||
return nil, rpcInternalError(err.Error(), "Could not "+
|
||||
@ -1409,7 +1409,7 @@ func handleEstimateStakeDiff(s *rpcServer, cmd interface{}, closeChan <-chan str
|
||||
// The expected stake difficulty. Average the number of fresh stake
|
||||
// since the last retarget to get the number of tickets per block,
|
||||
// then use that to estimate the next stake difficulty.
|
||||
bestHeight := s.server.blockManager.chain.BestSnapshot().Height
|
||||
bestHeight := chain.BestSnapshot().Height
|
||||
lastAdjustment := (bestHeight / activeNetParams.StakeDiffWindowSize) *
|
||||
activeNetParams.StakeDiffWindowSize
|
||||
nextAdjustment := ((bestHeight / activeNetParams.StakeDiffWindowSize) +
|
||||
@ -1525,7 +1525,7 @@ func handleExistsMissedTickets(s *rpcServer, cmd interface{}, closeChan <-chan s
|
||||
return nil, err
|
||||
}
|
||||
|
||||
exists := s.server.blockManager.chain.CheckMissedTickets(hashes)
|
||||
exists := s.server.chain.CheckMissedTickets(hashes)
|
||||
if len(exists) != len(hashes) {
|
||||
return nil, rpcInvalidError("Invalid missed ticket count "+
|
||||
"got %v, want %v", len(exists), len(hashes))
|
||||
@ -1551,7 +1551,7 @@ func handleExistsExpiredTickets(s *rpcServer, cmd interface{}, closeChan <-chan
|
||||
return nil, err
|
||||
}
|
||||
|
||||
exists := s.server.blockManager.chain.CheckExpiredTickets(hashes)
|
||||
exists := s.server.chain.CheckExpiredTickets(hashes)
|
||||
if len(exists) != len(hashes) {
|
||||
return nil, rpcInvalidError("Invalid expired ticket count "+
|
||||
"got %v, want %v", len(exists), len(hashes))
|
||||
@ -1577,7 +1577,7 @@ func handleExistsLiveTicket(s *rpcServer, cmd interface{}, closeChan <-chan stru
|
||||
return nil, rpcDecodeHexError(c.TxHash)
|
||||
}
|
||||
|
||||
return s.server.blockManager.chain.CheckLiveTicket(*hash), nil
|
||||
return s.server.chain.CheckLiveTicket(*hash), nil
|
||||
}
|
||||
|
||||
// handleExistsLiveTickets implements the existslivetickets command.
|
||||
@ -1589,7 +1589,7 @@ func handleExistsLiveTickets(s *rpcServer, cmd interface{}, closeChan <-chan str
|
||||
return nil, err
|
||||
}
|
||||
|
||||
exists := s.server.blockManager.chain.CheckLiveTickets(hashes)
|
||||
exists := s.server.chain.CheckLiveTickets(hashes)
|
||||
if len(exists) != len(hashes) {
|
||||
return nil, rpcInvalidError("Invalid live ticket count got "+
|
||||
"%v, want %v", len(exists), len(hashes))
|
||||
@ -1809,7 +1809,7 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i
|
||||
if err != nil {
|
||||
return nil, rpcDecodeHexError(c.Hash)
|
||||
}
|
||||
blk, err := s.server.blockManager.chain.BlockByHash(hash)
|
||||
blk, err := s.server.chain.BlockByHash(hash)
|
||||
if err != nil {
|
||||
return nil, &dcrjson.RPCError{
|
||||
Code: dcrjson.ErrRPCBlockNotFound,
|
||||
@ -2307,7 +2307,7 @@ func (state *gbtWorkState) updateBlockTemplate(s *rpcServer, useCoinbaseValue bo
|
||||
// generated.
|
||||
var msgBlock *wire.MsgBlock
|
||||
var targetDifficulty string
|
||||
best := s.server.blockManager.chain.BestSnapshot()
|
||||
best := s.server.chain.BestSnapshot()
|
||||
latestHash := best.Hash
|
||||
template := state.template
|
||||
if template == nil || state.prevHash == nil ||
|
||||
@ -2795,7 +2795,7 @@ func handleGetBlockTemplateRequest(s *rpcServer, request *dcrjson.TemplateReques
|
||||
}
|
||||
|
||||
// No point in generating or accepting work before the chain is synced.
|
||||
bestHeight := s.server.blockManager.chain.BestSnapshot().Height
|
||||
bestHeight := s.server.chain.BestSnapshot().Height
|
||||
if bestHeight != 0 && !s.server.blockManager.IsCurrent() {
|
||||
return nil, &dcrjson.RPCError{
|
||||
Code: dcrjson.ErrRPCClientInInitialDownload,
|
||||
@ -2944,13 +2944,13 @@ func handleGetBlockTemplateProposal(s *rpcServer, request *dcrjson.TemplateReque
|
||||
block := dcrutil.NewBlock(&msgBlock)
|
||||
|
||||
// Ensure the block is building from the expected previous block.
|
||||
expectedPrevHash := &s.server.blockManager.chain.BestSnapshot().Hash
|
||||
expectedPrevHash := &s.server.chain.BestSnapshot().Hash
|
||||
prevHash := &block.MsgBlock().Header.PrevBlock
|
||||
if *expectedPrevHash != *prevHash {
|
||||
return "bad-prevblk", nil
|
||||
}
|
||||
|
||||
err = s.server.blockManager.chain.CheckConnectBlockTemplate(block)
|
||||
err = s.server.chain.CheckConnectBlockTemplate(block)
|
||||
if err != nil {
|
||||
if _, ok := err.(blockchain.RuleError); !ok {
|
||||
errStr := fmt.Sprintf("Failed to process block "+
|
||||
@ -3164,7 +3164,7 @@ func handleGetHeaders(s *rpcServer, cmd interface{}, closeChan <-chan struct{})
|
||||
locators[i] = &blockLocators[i]
|
||||
}
|
||||
|
||||
chain := s.server.blockManager.chain
|
||||
chain := s.server.chain
|
||||
headers := chain.LocateHeaders(locators, &hashStop)
|
||||
|
||||
// Return the serialized block headers as hex-encoded strings.
|
||||
@ -4040,7 +4040,7 @@ func handleGetWorkRequest(s *rpcServer) (interface{}, error) {
|
||||
// it has been at least one minute since the last template was
|
||||
// generated.
|
||||
lastTxUpdate := s.server.txMemPool.LastUpdated()
|
||||
best := s.server.blockManager.chain.BestSnapshot()
|
||||
best := s.server.chain.BestSnapshot()
|
||||
msgBlock := state.msgBlock
|
||||
|
||||
// The current code pulls down a new template every second, however
|
||||
@ -4338,7 +4338,7 @@ func handleGetWork(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (in
|
||||
}
|
||||
|
||||
// No point in generating or accepting work before the chain is synced.
|
||||
bestHeight := s.server.blockManager.chain.BestSnapshot().Height
|
||||
bestHeight := s.server.chain.BestSnapshot().Height
|
||||
if bestHeight != 0 && !s.server.blockManager.IsCurrent() {
|
||||
return nil, &dcrjson.RPCError{
|
||||
Code: dcrjson.ErrRPCClientInInitialDownload,
|
||||
@ -4402,7 +4402,7 @@ func handleHelp(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (inter
|
||||
|
||||
// handleLiveTickets implements the livetickets command.
|
||||
func handleLiveTickets(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||
lt, err := s.server.blockManager.chain.LiveTickets()
|
||||
lt, err := s.server.chain.LiveTickets()
|
||||
if err != nil {
|
||||
return nil, rpcInternalError("Could not get live tickets "+
|
||||
err.Error(), "")
|
||||
@ -4418,7 +4418,7 @@ func handleLiveTickets(s *rpcServer, cmd interface{}, closeChan <-chan struct{})
|
||||
|
||||
// handleMissedTickets implements the missedtickets command.
|
||||
func handleMissedTickets(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||
mt, err := s.server.blockManager.chain.MissedTickets()
|
||||
mt, err := s.server.chain.MissedTickets()
|
||||
if err != nil {
|
||||
return nil, rpcInternalError("Could not get missed tickets "+
|
||||
err.Error(), "")
|
||||
@ -4447,8 +4447,8 @@ func handlePing(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (inter
|
||||
|
||||
// handleRebroadcastMissed implements the rebroadcastmissed command.
|
||||
func handleRebroadcastMissed(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||
best := s.server.blockManager.chain.BestSnapshot()
|
||||
mt, err := s.server.blockManager.chain.MissedTickets()
|
||||
best := s.server.chain.BestSnapshot()
|
||||
mt, err := s.server.chain.MissedTickets()
|
||||
if err != nil {
|
||||
return nil, rpcInternalError("Could not get missed tickets "+
|
||||
err.Error(), "")
|
||||
@ -4476,7 +4476,7 @@ func handleRebroadcastMissed(s *rpcServer, cmd interface{}, closeChan <-chan str
|
||||
|
||||
// handleRebroadcastWinners implements the rebroadcastwinners command.
|
||||
func handleRebroadcastWinners(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||
bestHeight := s.server.blockManager.chain.BestSnapshot().Height
|
||||
bestHeight := s.server.chain.BestSnapshot().Height
|
||||
blocks, err := s.server.blockManager.TipGeneration()
|
||||
if err != nil {
|
||||
return nil, rpcInternalError("Could not get generation "+
|
||||
@ -4485,7 +4485,7 @@ func handleRebroadcastWinners(s *rpcServer, cmd interface{}, closeChan <-chan st
|
||||
|
||||
for i := range blocks {
|
||||
winningTickets, _, _, err :=
|
||||
s.server.blockManager.chain.LotteryDataForBlock(&blocks[i])
|
||||
s.server.chain.LotteryDataForBlock(&blocks[i])
|
||||
if err != nil {
|
||||
return nil, rpcInternalError("Lottery data for block "+
|
||||
"failed: "+err.Error(), "")
|
||||
@ -5051,7 +5051,7 @@ func handleSendRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan st
|
||||
// JSON-RPC error is returned to the client with the
|
||||
// deserialization error code (to match bitcoind behavior).
|
||||
if rErr, ok := err.(mempool.RuleError); ok {
|
||||
err = fmt.Errorf("Rejected transaction %v: %v", tx.Hash(),
|
||||
err = fmt.Errorf("rejected transaction %v: %v", tx.Hash(),
|
||||
err)
|
||||
rpcsLog.Debugf("%v", err)
|
||||
txRuleErr, ok := rErr.Err.(mempool.TxRuleError)
|
||||
@ -5376,7 +5376,7 @@ func ticketFeeInfoForRange(s *rpcServer, start int64, end int64, txType stake.Tx
|
||||
func handleTicketFeeInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||
c := cmd.(*dcrjson.TicketFeeInfoCmd)
|
||||
|
||||
bestHeight := s.server.blockManager.chain.BestSnapshot().Height
|
||||
bestHeight := s.server.chain.BestSnapshot().Height
|
||||
|
||||
// Memory pool first.
|
||||
feeInfoMempool := feeInfoForMempool(s, stake.TxTypeSStx)
|
||||
@ -5462,10 +5462,9 @@ func handleTicketsForAddress(s *rpcServer, cmd interface{}, closeChan <-chan str
|
||||
return nil, rpcInvalidError("Invalid address: %v", err)
|
||||
}
|
||||
|
||||
tickets, err := s.server.blockManager.chain.TicketsWithAddress(addr)
|
||||
tickets, err := s.server.chain.TicketsWithAddress(addr)
|
||||
if err != nil {
|
||||
return nil, rpcInternalError(err.Error(),
|
||||
"Could not obtain tickets")
|
||||
return nil, rpcInternalError(err.Error(), "could not obtain tickets")
|
||||
}
|
||||
|
||||
ticketStrings := make([]string, len(tickets))
|
||||
@ -5487,15 +5486,14 @@ func handleTicketVWAP(s *rpcServer, cmd interface{}, closeChan <-chan struct{})
|
||||
|
||||
// The default VWAP is for the past WorkDiffWindows * WorkDiffWindowSize
|
||||
// many blocks.
|
||||
bestHeight := s.server.blockManager.chain.BestSnapshot().Height
|
||||
bestHeight := s.server.chain.BestSnapshot().Height
|
||||
var start uint32
|
||||
if c.Start == nil {
|
||||
toEval := activeNetParams.WorkDiffWindows *
|
||||
activeNetParams.WorkDiffWindowSize
|
||||
startI64 := bestHeight - toEval
|
||||
|
||||
// Use 1 as the first block if there aren't
|
||||
// enough blocks.
|
||||
// Use 1 as the first block if there aren't enough blocks.
|
||||
if startI64 <= 0 {
|
||||
start = 1
|
||||
} else {
|
||||
@ -5544,7 +5542,7 @@ func handleTicketVWAP(s *rpcServer, cmd interface{}, closeChan <-chan struct{})
|
||||
func handleTxFeeInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||
c := cmd.(*dcrjson.TxFeeInfoCmd)
|
||||
|
||||
bestHeight := s.server.blockManager.chain.BestSnapshot().Height
|
||||
bestHeight := s.server.chain.BestSnapshot().Height
|
||||
|
||||
// Memory pool first.
|
||||
feeInfoMempool := feeInfoForMempool(s, stake.TxTypeRegular)
|
||||
@ -6432,7 +6430,7 @@ func newRPCServer(listenAddrs []string, generator *BlkTmplGenerator, s *server)
|
||||
rpc := rpcServer{
|
||||
server: s,
|
||||
generator: generator,
|
||||
chain: s.blockManager.chain,
|
||||
chain: s.chain,
|
||||
statusLines: make(map[int]string),
|
||||
workState: newWorkState(),
|
||||
templatePool: make(map[[merkleRootPairSize]byte]*workStateBlockInfo),
|
||||
|
||||
@ -2190,7 +2190,7 @@ func handleRescan(wsc *wsClient, icmd interface{}) (interface{}, error) {
|
||||
|
||||
// Iterate over each block in the request and rescan. When a block
|
||||
// contains relevant transactions, add it to the response.
|
||||
bc := wsc.server.server.blockManager.chain
|
||||
bc := wsc.server.chain
|
||||
var lastBlockHash *chainhash.Hash
|
||||
for i := range blockHashes {
|
||||
block, err := bc.BlockByHash(&blockHashes[i])
|
||||
|
||||
106
server.go
106
server.go
@ -194,6 +194,7 @@ type server struct {
|
||||
rpcServer *rpcServer
|
||||
blockManager *blockManager
|
||||
bg *BgBlkTmplGenerator
|
||||
chain *blockchain.BlockChain
|
||||
txMemPool *mempool.TxPool
|
||||
feeEstimator *fees.Estimator
|
||||
cpuMiner *CPUMiner
|
||||
@ -271,7 +272,7 @@ func newServerPeer(s *server, isPersistent bool) *serverPeer {
|
||||
// newestBlock returns the current best block hash and height using the format
|
||||
// required by the configuration for the peer package.
|
||||
func (sp *serverPeer) newestBlock() (*chainhash.Hash, int64, error) {
|
||||
best := sp.server.blockManager.chain.BestSnapshot()
|
||||
best := sp.server.chain.BestSnapshot()
|
||||
return &best.Hash, best.Height, nil
|
||||
}
|
||||
|
||||
@ -532,7 +533,7 @@ func (sp *serverPeer) OnGetMiningState(p *peer.Peer, msg *wire.MsgGetMiningState
|
||||
// Access the block manager and get the list of best blocks to mine on.
|
||||
bm := sp.server.blockManager
|
||||
mp := sp.server.txMemPool
|
||||
best := bm.chain.BestSnapshot()
|
||||
best := sp.server.chain.BestSnapshot()
|
||||
|
||||
// Send out blank mining states if it's early in the blockchain.
|
||||
if best.Height < activeNetParams.StakeValidationHeight-1 {
|
||||
@ -559,7 +560,7 @@ func (sp *serverPeer) OnGetMiningState(p *peer.Peer, msg *wire.MsgGetMiningState
|
||||
// per mining state message. There is nothing to send when there are no
|
||||
// eligible blocks.
|
||||
blockHashes := SortParentsByVotes(mp, best.Hash, children,
|
||||
bm.server.chainParams)
|
||||
bm.cfg.ChainParams)
|
||||
numBlocks := len(blockHashes)
|
||||
if numBlocks == 0 {
|
||||
return
|
||||
@ -777,7 +778,7 @@ func (sp *serverPeer) OnGetBlocks(p *peer.Peer, msg *wire.MsgGetBlocks) {
|
||||
// Use the block after the genesis block if no other blocks in the
|
||||
// provided locator are known. This does mean the client will start
|
||||
// over with the genesis block if unknown block locators are provided.
|
||||
chain := sp.server.blockManager.chain
|
||||
chain := sp.server.chain
|
||||
hashList := chain.LocateBlocks(msg.BlockLocatorHashes, &msg.HashStop,
|
||||
wire.MaxBlocksPerMsg)
|
||||
|
||||
@ -818,7 +819,7 @@ func (sp *serverPeer) OnGetHeaders(p *peer.Peer, msg *wire.MsgGetHeaders) {
|
||||
// Use the block after the genesis block if no other blocks in the
|
||||
// provided locator are known. This does mean the client will start
|
||||
// over with the genesis block if unknown block locators are provided.
|
||||
chain := sp.server.blockManager.chain
|
||||
chain := sp.server.chain
|
||||
headers := chain.LocateHeaders(msg.BlockLocatorHashes, &msg.HashStop)
|
||||
|
||||
// Send found headers to the requesting peer.
|
||||
@ -892,7 +893,7 @@ func (sp *serverPeer) OnGetCFilter(p *peer.Peer, msg *wire.MsgGetCFilter) {
|
||||
// block was disconnected, or this has always been a sidechain block) build
|
||||
// the filter on the spot.
|
||||
if len(filterBytes) == 0 {
|
||||
block, err := sp.server.blockManager.chain.BlockByHash(&msg.BlockHash)
|
||||
block, err := sp.server.chain.BlockByHash(&msg.BlockHash)
|
||||
if err != nil {
|
||||
peerLog.Errorf("OnGetCFilter: failed to fetch non-mainchain "+
|
||||
"block %v: %v", &msg.BlockHash, err)
|
||||
@ -961,7 +962,7 @@ func (sp *serverPeer) OnGetCFHeaders(p *peer.Peer, msg *wire.MsgGetCFHeaders) {
|
||||
// Use the block after the genesis block if no other blocks in the provided
|
||||
// locator are known. This does mean the served filter headers will start
|
||||
// over at the genesis block if unknown block locators are provided.
|
||||
chain := sp.server.blockManager.chain
|
||||
chain := sp.server.chain
|
||||
hashList := chain.LocateBlocks(msg.BlockLocatorHashes, &msg.HashStop,
|
||||
wire.MaxCFHeadersPerMsg)
|
||||
if len(hashList) == 0 {
|
||||
@ -1158,11 +1159,11 @@ func (s *server) PruneRebroadcastInventory() {
|
||||
// both websocket and getblocktemplate long poll clients of the passed
|
||||
// transactions. This function should be called whenever new transactions
|
||||
// are added to the mempool.
|
||||
func (s *server) AnnounceNewTransactions(newTxs []*dcrutil.Tx) {
|
||||
func (s *server) AnnounceNewTransactions(txns []*dcrutil.Tx) {
|
||||
// Generate and relay inventory vectors for all newly accepted
|
||||
// transactions into the memory pool due to the original being
|
||||
// accepted.
|
||||
for _, tx := range newTxs {
|
||||
for _, tx := range txns {
|
||||
// Generate the inventory vector and relay it.
|
||||
iv := wire.NewInvVect(wire.InvTypeTx, tx.Hash())
|
||||
s.RelayInventory(iv, tx, false)
|
||||
@ -1173,12 +1174,21 @@ func (s *server) AnnounceNewTransactions(newTxs []*dcrutil.Tx) {
|
||||
|
||||
// Potentially notify any getblocktemplate long poll clients
|
||||
// about stale block templates due to the new transaction.
|
||||
s.rpcServer.gbtWorkState.NotifyMempoolTx(
|
||||
s.txMemPool.LastUpdated())
|
||||
s.rpcServer.gbtWorkState.NotifyMempoolTx(s.txMemPool.LastUpdated())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TransactionConfirmed marks the provided single confirmation transaction as
|
||||
// no longer needing rebroadcasting.
|
||||
func (s *server) TransactionConfirmed(tx *dcrutil.Tx) {
|
||||
// Rebroadcasting is only necessary when the RPC server is active.
|
||||
if s.rpcServer != nil {
|
||||
iv := wire.NewInvVect(wire.InvTypeTx, tx.Hash())
|
||||
s.RemoveRebroadcastInventory(iv)
|
||||
}
|
||||
}
|
||||
|
||||
// pushTxMsg sends a tx message for the provided transaction hash to the
|
||||
// connected peer. An error is returned if the transaction hash is not known.
|
||||
func (s *server) pushTxMsg(sp *serverPeer, hash *chainhash.Hash, doneChan chan<- struct{}, waitChan <-chan struct{}) error {
|
||||
@ -1212,7 +1222,7 @@ func (s *server) pushTxMsg(sp *serverPeer, hash *chainhash.Hash, doneChan chan<-
|
||||
// pushBlockMsg sends a block message for the provided block hash to the
|
||||
// connected peer. An error is returned if the block hash is not known.
|
||||
func (s *server) pushBlockMsg(sp *serverPeer, hash *chainhash.Hash, doneChan chan<- struct{}, waitChan <-chan struct{}) error {
|
||||
block, err := sp.server.blockManager.chain.BlockByHash(hash)
|
||||
block, err := sp.server.chain.BlockByHash(hash)
|
||||
if err != nil {
|
||||
peerLog.Tracef("Unable to fetch requested block hash %v: %v",
|
||||
hash, err)
|
||||
@ -1244,7 +1254,7 @@ func (s *server) pushBlockMsg(sp *serverPeer, hash *chainhash.Hash, doneChan cha
|
||||
// to trigger it to issue another getblocks message for the next
|
||||
// batch of inventory.
|
||||
if sendInv {
|
||||
best := sp.server.blockManager.chain.BestSnapshot()
|
||||
best := sp.server.chain.BestSnapshot()
|
||||
invMsg := wire.NewMsgInvSizeHint(1)
|
||||
iv := wire.NewInvVect(wire.InvTypeBlock, &best.Hash)
|
||||
invMsg.AddInvVect(iv)
|
||||
@ -2016,9 +2026,9 @@ out:
|
||||
delete(pendingInvs, *msg)
|
||||
|
||||
case broadcastPruneInventory:
|
||||
best := s.blockManager.chain.BestSnapshot()
|
||||
best := s.chain.BestSnapshot()
|
||||
nextStakeDiff, err :=
|
||||
s.blockManager.chain.CalcNextRequiredStakeDifficulty()
|
||||
s.chain.CalcNextRequiredStakeDifficulty()
|
||||
if err != nil {
|
||||
srvrLog.Errorf("Failed to get next stake difficulty: %v",
|
||||
err)
|
||||
@ -2058,7 +2068,7 @@ out:
|
||||
// ticket has been revived.
|
||||
if txType == stake.TxTypeSSRtx {
|
||||
refSStxHash := tx.MsgTx().TxIn[0].PreviousOutPoint.Hash
|
||||
if !s.blockManager.chain.CheckLiveTicket(refSStxHash) {
|
||||
if !s.chain.CheckLiveTicket(refSStxHash) {
|
||||
delete(pendingInvs, iv)
|
||||
srvrLog.Debugf("Pending revocation broadcast "+
|
||||
"inventory for tx %v removed. "+
|
||||
@ -2534,11 +2544,24 @@ func newServer(listenAddrs []string, db database.DB, chainParams *chaincfg.Param
|
||||
if len(indexes) > 0 {
|
||||
indexManager = indexers.NewManager(db, indexes, chainParams)
|
||||
}
|
||||
bm, err := newBlockManager(&s, indexManager, interrupt)
|
||||
|
||||
// Create a new block chain instance with the appropriate configuration.
|
||||
s.chain, err = blockchain.New(&blockchain.Config{
|
||||
DB: s.db,
|
||||
Interrupt: interrupt,
|
||||
ChainParams: s.chainParams,
|
||||
TimeSource: s.timeSource,
|
||||
Notifications: func(notification *blockchain.Notification) {
|
||||
if s.blockManager != nil {
|
||||
s.blockManager.handleBlockchainNotification(notification)
|
||||
}
|
||||
},
|
||||
SigCache: s.sigCache,
|
||||
IndexManager: indexManager,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.blockManager = bm
|
||||
|
||||
txC := mempool.Config{
|
||||
Policy: mempool.Policy{
|
||||
@ -2552,23 +2575,23 @@ func newServer(listenAddrs []string, db database.DB, chainParams *chaincfg.Param
|
||||
MinRelayTxFee: cfg.minRelayTxFee,
|
||||
AllowOldVotes: cfg.AllowOldVotes,
|
||||
StandardVerifyFlags: func() (txscript.ScriptFlags, error) {
|
||||
return standardScriptVerifyFlags(bm.chain)
|
||||
return standardScriptVerifyFlags(s.chain)
|
||||
},
|
||||
AcceptSequenceLocks: bm.chain.IsFixSeqLocksAgendaActive,
|
||||
AcceptSequenceLocks: s.chain.IsFixSeqLocksAgendaActive,
|
||||
},
|
||||
ChainParams: chainParams,
|
||||
NextStakeDifficulty: func() (int64, error) {
|
||||
return bm.chain.BestSnapshot().NextStakeDiff, nil
|
||||
return s.chain.BestSnapshot().NextStakeDiff, nil
|
||||
},
|
||||
FetchUtxoView: bm.chain.FetchUtxoView,
|
||||
BlockByHash: bm.chain.BlockByHash,
|
||||
BestHash: func() *chainhash.Hash { return &bm.chain.BestSnapshot().Hash },
|
||||
BestHeight: func() int64 { return bm.chain.BestSnapshot().Height },
|
||||
CalcSequenceLock: bm.chain.CalcSequenceLock,
|
||||
SubsidyCache: bm.chain.FetchSubsidyCache(),
|
||||
FetchUtxoView: s.chain.FetchUtxoView,
|
||||
BlockByHash: s.chain.BlockByHash,
|
||||
BestHash: func() *chainhash.Hash { return &s.chain.BestSnapshot().Hash },
|
||||
BestHeight: func() int64 { return s.chain.BestSnapshot().Height },
|
||||
CalcSequenceLock: s.chain.CalcSequenceLock,
|
||||
SubsidyCache: s.chain.FetchSubsidyCache(),
|
||||
SigCache: s.sigCache,
|
||||
PastMedianTime: func() time.Time {
|
||||
return bm.chain.BestSnapshot().MedianTime
|
||||
return s.chain.BestSnapshot().MedianTime
|
||||
},
|
||||
AddrIndex: s.addrIndex,
|
||||
ExistsAddrIndex: s.existsAddrIndex,
|
||||
@ -2581,6 +2604,27 @@ func newServer(listenAddrs []string, db database.DB, chainParams *chaincfg.Param
|
||||
},
|
||||
}
|
||||
s.txMemPool = mempool.New(&txC)
|
||||
s.blockManager, err = newBlockManager(&blockManagerConfig{
|
||||
PeerNotifier: &s,
|
||||
Chain: s.chain,
|
||||
ChainParams: s.chainParams,
|
||||
TimeSource: s.timeSource,
|
||||
FeeEstimator: s.feeEstimator,
|
||||
TxMemPool: s.txMemPool,
|
||||
BgBlkTmplGenerator: s.bg,
|
||||
NotifyWinningTickets: func(wtnd *WinningTicketsNtfnData) {
|
||||
if s.rpcServer != nil {
|
||||
s.rpcServer.ntfnMgr.NotifyWinningTickets(wtnd)
|
||||
}
|
||||
},
|
||||
PruneRebroadcastInventory: s.PruneRebroadcastInventory,
|
||||
RpcServer: func() *rpcServer {
|
||||
return s.rpcServer
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create the mining policy and block template generator based on the
|
||||
// configuration options.
|
||||
@ -2594,7 +2638,7 @@ func newServer(listenAddrs []string, db database.DB, chainParams *chaincfg.Param
|
||||
TxMinFreeFee: cfg.minRelayTxFee,
|
||||
}
|
||||
tg := newBlkTmplGenerator(&policy, s.txMemPool, s.timeSource, s.sigCache,
|
||||
s.chainParams, bm.chain, bm)
|
||||
s.chainParams, s.chain, s.blockManager)
|
||||
|
||||
// Create the background block template generator if the config has a
|
||||
// mining address.
|
||||
@ -2607,9 +2651,9 @@ func newServer(listenAddrs []string, db database.DB, chainParams *chaincfg.Param
|
||||
PermitConnectionlessMining: cfg.SimNet,
|
||||
BlockTemplateGenerator: tg,
|
||||
MiningAddrs: cfg.miningAddrs,
|
||||
ProcessBlock: bm.ProcessBlock,
|
||||
ProcessBlock: s.blockManager.ProcessBlock,
|
||||
ConnectedCount: s.ConnectedCount,
|
||||
IsCurrent: bm.IsCurrent,
|
||||
IsCurrent: s.blockManager.IsCurrent,
|
||||
})
|
||||
|
||||
// Only setup a function to return new addresses to connect to when
|
||||
|
||||
Loading…
Reference in New Issue
Block a user