mirror of
https://github.com/FlipsideCrypto/dcrd.git
synced 2026-02-06 10:56:47 +00:00
mempool/mining: Introduce TxSource interface.
Upstream commit 2b6a9a56e5.
NOTE: This is only merging in the upstream changes, so while they are
useful for Decred as well, this merge commit does fully separate the
mempool as upstream does due to the new functionality provided by
Decred.
This commit is contained in:
commit
9031d8574e
13
cpuminer.go
13
cpuminer.go
@ -60,6 +60,7 @@ var (
|
||||
type CPUMiner struct {
|
||||
sync.Mutex
|
||||
policy *miningPolicy
|
||||
txSource TxSource
|
||||
server *server
|
||||
numWorkers uint32
|
||||
started bool
|
||||
@ -212,7 +213,7 @@ func (m *CPUMiner) solveBlock(msgBlock *wire.MsgBlock, ticker *time.Ticker,
|
||||
|
||||
// Initial state.
|
||||
lastGenerated := time.Now()
|
||||
lastTxUpdate := m.server.txMemPool.LastUpdated()
|
||||
lastTxUpdate := m.txSource.LastUpdated()
|
||||
hashesCompleted := uint64(0)
|
||||
|
||||
// Note that the entire extra nonce range is iterated and the offset is
|
||||
@ -244,9 +245,10 @@ func (m *CPUMiner) solveBlock(msgBlock *wire.MsgBlock, ticker *time.Ticker,
|
||||
// has been updated since the block template was
|
||||
// generated and it has been at least 3 seconds,
|
||||
// or if it's been one minute.
|
||||
if (lastTxUpdate != m.server.txMemPool.LastUpdated() &&
|
||||
if (lastTxUpdate != m.txSource.LastUpdated() &&
|
||||
time.Now().After(lastGenerated.Add(3*time.Second))) ||
|
||||
time.Now().After(lastGenerated.Add(60*time.Second)) {
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@ -327,8 +329,7 @@ out:
|
||||
// Create a new block template using the available transactions
|
||||
// in the memory pool as a source of transactions to potentially
|
||||
// include in the block.
|
||||
template, err := NewBlockTemplate(m.policy, m.server.txMemPool,
|
||||
payToAddr)
|
||||
template, err := NewBlockTemplate(m.policy, m.server, payToAddr)
|
||||
m.submitBlockLock.Unlock()
|
||||
if err != nil {
|
||||
errStr := fmt.Sprintf("Failed to create new block "+
|
||||
@ -607,8 +608,7 @@ func (m *CPUMiner) GenerateNBlocks(n uint32) ([]*chainhash.Hash, error) {
|
||||
// Create a new block template using the available transactions
|
||||
// in the memory pool as a source of transactions to potentially
|
||||
// include in the block.
|
||||
template, err := NewBlockTemplate(m.policy, m.server.txMemPool,
|
||||
payToAddr)
|
||||
template, err := NewBlockTemplate(m.policy, m.server, payToAddr)
|
||||
m.submitBlockLock.Unlock()
|
||||
if err != nil {
|
||||
errStr := fmt.Sprintf("Failed to create new block "+
|
||||
@ -652,6 +652,7 @@ func (m *CPUMiner) GenerateNBlocks(n uint32) ([]*chainhash.Hash, error) {
|
||||
func newCPUMiner(policy *miningPolicy, s *server) *CPUMiner {
|
||||
return &CPUMiner{
|
||||
policy: policy,
|
||||
txSource: s.txMemPool,
|
||||
server: s,
|
||||
numWorkers: defaultNumWorkers,
|
||||
updateNumWorkers: make(chan struct{}),
|
||||
|
||||
78
mempool.go
78
mempool.go
@ -74,22 +74,6 @@ const (
|
||||
maxNullDataOutputs = 4
|
||||
)
|
||||
|
||||
// TxDesc is a descriptor containing a transaction in the mempool and the
|
||||
// metadata we store about it.
|
||||
type TxDesc struct {
|
||||
Tx *dcrutil.Tx // Transaction.
|
||||
Type stake.TxType // Transcation type.
|
||||
Added time.Time // Time when added to pool.
|
||||
Height int64 // Blockheight when added to pool.
|
||||
Fee int64 // Transaction fees.
|
||||
StartingPriority float64 // Priority when added to the pool.
|
||||
}
|
||||
|
||||
// GetType returns what TxType a given TxDesc is.
|
||||
func (td *TxDesc) GetType() stake.TxType {
|
||||
return td.Type
|
||||
}
|
||||
|
||||
// VoteTx is a struct describing a block vote (SSGen).
|
||||
type VoteTx struct {
|
||||
SsgenHash chainhash.Hash // Vote
|
||||
@ -97,6 +81,16 @@ type VoteTx struct {
|
||||
Vote bool
|
||||
}
|
||||
|
||||
// mempoolTxDesc is a descriptor containing a transaction in the mempool along
|
||||
// with additional metadata.
|
||||
type mempoolTxDesc struct {
|
||||
miningTxDesc
|
||||
|
||||
// StartingPriority is the priority of the transaction when it was added
|
||||
// to the pool.
|
||||
StartingPriority float64
|
||||
}
|
||||
|
||||
// txMemPool is used as a source of transactions that need to be mined into
|
||||
// blocks and relayed to other peers. It is safe for concurrent access from
|
||||
// multiple peers.
|
||||
@ -106,7 +100,7 @@ type txMemPool struct {
|
||||
|
||||
sync.RWMutex
|
||||
server *server
|
||||
pool map[chainhash.Hash]*TxDesc
|
||||
pool map[chainhash.Hash]*mempoolTxDesc
|
||||
orphans map[chainhash.Hash]*dcrutil.Tx
|
||||
orphansByPrev map[chainhash.Hash]map[chainhash.Hash]*dcrutil.Tx
|
||||
addrindex map[string]map[chainhash.Hash]struct{} // maps address to txs
|
||||
@ -358,6 +352,9 @@ func (mp *txMemPool) SortParentsByVotes(currentTopBlock chainhash.Hash,
|
||||
return sortedBlocks, err
|
||||
}
|
||||
|
||||
// Ensure the txMemPool type implements the mining.TxSource interface.
|
||||
var _ TxSource = (*txMemPool)(nil)
|
||||
|
||||
// removeOrphan is the internal function which implements the public
|
||||
// RemoveOrphan. See the comment for RemoveOrphan for more details.
|
||||
//
|
||||
@ -661,12 +658,14 @@ func (mp *txMemPool) addTransaction(txStore blockchain.TxStore, tx *dcrutil.Tx,
|
||||
|
||||
// Add the transaction to the pool and mark the referenced outpoints
|
||||
// as spent by the pool.
|
||||
mp.pool[*tx.Sha()] = &TxDesc{
|
||||
Tx: tx,
|
||||
Type: txType,
|
||||
Added: time.Now(),
|
||||
Height: height,
|
||||
Fee: fee,
|
||||
mp.pool[*tx.Sha()] = &mempoolTxDesc{
|
||||
miningTxDesc: miningTxDesc{
|
||||
Tx: tx,
|
||||
Type: txType,
|
||||
Added: time.Now(),
|
||||
Height: height,
|
||||
Fee: fee,
|
||||
},
|
||||
StartingPriority: calcPriority(tx.MsgTx(), txStore, height),
|
||||
}
|
||||
for _, txIn := range tx.MsgTx().TxIn {
|
||||
@ -952,8 +951,8 @@ func (mp *txMemPool) FilterTransactionsByAddress(
|
||||
if txs, exists := mp.addrindex[addr.EncodeAddress()]; exists {
|
||||
addressTxs := make([]*dcrutil.Tx, 0, len(txs))
|
||||
for txHash := range txs {
|
||||
if tx, exists := mp.pool[txHash]; exists {
|
||||
addressTxs = append(addressTxs, tx.Tx)
|
||||
if txD, exists := mp.pool[txHash]; exists {
|
||||
addressTxs = append(addressTxs, txD.Tx)
|
||||
}
|
||||
}
|
||||
return addressTxs, nil
|
||||
@ -1072,7 +1071,7 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *dcrutil.Tx, isNew,
|
||||
if txType == stake.TxTypeSSGen {
|
||||
ssGenAlreadyFound := 0
|
||||
for _, mpTx := range mp.pool {
|
||||
if mpTx.GetType() == stake.TxTypeSSGen {
|
||||
if mpTx.Type == stake.TxTypeSSGen {
|
||||
if mpTx.Tx.MsgTx().TxIn[1].PreviousOutPoint ==
|
||||
tx.MsgTx().TxIn[1].PreviousOutPoint {
|
||||
ssGenAlreadyFound++
|
||||
@ -1090,7 +1089,7 @@ func (mp *txMemPool) maybeAcceptTransaction(tx *dcrutil.Tx, isNew,
|
||||
|
||||
if txType == stake.TxTypeSSRtx {
|
||||
for _, mpTx := range mp.pool {
|
||||
if mpTx.GetType() == stake.TxTypeSSRtx {
|
||||
if mpTx.Type == stake.TxTypeSSRtx {
|
||||
if mpTx.Tx.MsgTx().TxIn[0].PreviousOutPoint ==
|
||||
tx.MsgTx().TxIn[0].PreviousOutPoint {
|
||||
str := fmt.Sprintf("transaction %v in the pool "+
|
||||
@ -1645,11 +1644,11 @@ func (mp *txMemPool) TxShas() []*chainhash.Hash {
|
||||
// The descriptors are to be treated as read only.
|
||||
//
|
||||
// This function is safe for concurrent access.
|
||||
func (mp *txMemPool) TxDescs() []*TxDesc {
|
||||
func (mp *txMemPool) TxDescs() []*mempoolTxDesc {
|
||||
mp.RLock()
|
||||
defer mp.RUnlock()
|
||||
|
||||
descs := make([]*TxDesc, len(mp.pool))
|
||||
descs := make([]*mempoolTxDesc, len(mp.pool))
|
||||
i := 0
|
||||
for _, desc := range mp.pool {
|
||||
descs[i] = desc
|
||||
@ -1659,6 +1658,25 @@ func (mp *txMemPool) TxDescs() []*TxDesc {
|
||||
return descs
|
||||
}
|
||||
|
||||
// MiningDescs returns a slice of mining descriptors for all the transactions
|
||||
// in the pool.
|
||||
//
|
||||
// This is part of the TxSource interface implementation and is safe for
|
||||
// concurrent access as required by the interface contract.
|
||||
func (mp *txMemPool) MiningDescs() []*miningTxDesc {
|
||||
mp.RLock()
|
||||
defer mp.RUnlock()
|
||||
|
||||
descs := make([]*miningTxDesc, len(mp.pool))
|
||||
i := 0
|
||||
for _, desc := range mp.pool {
|
||||
descs[i] = &desc.miningTxDesc
|
||||
i++
|
||||
}
|
||||
|
||||
return descs
|
||||
}
|
||||
|
||||
// LastUpdated returns the last time a transaction was added to or removed from
|
||||
// the main pool. It does not include the orphan pool.
|
||||
//
|
||||
@ -1691,7 +1709,7 @@ func (mp *txMemPool) CheckIfTxsExist(hashes []chainhash.Hash) bool {
|
||||
func newTxMemPool(server *server) *txMemPool {
|
||||
memPool := &txMemPool{
|
||||
server: server,
|
||||
pool: make(map[chainhash.Hash]*TxDesc),
|
||||
pool: make(map[chainhash.Hash]*mempoolTxDesc),
|
||||
orphans: make(map[chainhash.Hash]*dcrutil.Tx),
|
||||
orphansByPrev: make(map[chainhash.Hash]map[chainhash.Hash]*dcrutil.Tx),
|
||||
outpoints: make(map[wire.OutPoint]*dcrutil.Tx),
|
||||
|
||||
141
mining.go
141
mining.go
@ -40,6 +40,45 @@ const (
|
||||
kilobyte = 1000
|
||||
)
|
||||
|
||||
// miningTxDesc is a descriptor about a transaction in a transaction source
|
||||
// along with additional metadata.
|
||||
type miningTxDesc struct {
|
||||
// Tx is the transaction associated with the entry.
|
||||
Tx *dcrutil.Tx
|
||||
|
||||
// Type is the type of the transaction associated with the entry.
|
||||
Type stake.TxType
|
||||
|
||||
// Added is the time when the entry was added to the source pool.
|
||||
Added time.Time
|
||||
|
||||
// Height is the block height when the entry was added to the the source
|
||||
// pool.
|
||||
Height int64
|
||||
|
||||
// Fee is the total fee the transaction associated with the entry pays.
|
||||
Fee int64
|
||||
}
|
||||
|
||||
// TxSource represents a source of transactions to consider for inclusion in
|
||||
// new blocks.
|
||||
//
|
||||
// The interface contract requires that all of these methods are safe for
|
||||
// concurrent access with respect to the source.
|
||||
type TxSource interface {
|
||||
// LastUpdated returns the last time a transaction was added to or
|
||||
// removed from the source pool.
|
||||
LastUpdated() time.Time
|
||||
|
||||
// MiningDescs returns a slice of mining descriptors for all the
|
||||
// transactions in the source pool.
|
||||
MiningDescs() []*miningTxDesc
|
||||
|
||||
// HaveTransaction returns whether or not the passed transaction hash
|
||||
// exists in the source pool.
|
||||
HaveTransaction(hash *chainhash.Hash) bool
|
||||
}
|
||||
|
||||
// miningPolicy houses the policy (configuration parameters) which is used to
|
||||
// control the generation of block templates. See the documentation for
|
||||
// NewBlockTemplate for more details on each of these parameters are used.
|
||||
@ -74,7 +113,7 @@ type txPrioItem struct {
|
||||
|
||||
// dependsOn holds a map of transaction hashes which this one depends
|
||||
// on. It will only be set when the transaction references other
|
||||
// transactions in the memory pool and hence must come after them in
|
||||
// transactions in the source pool and hence must come after them in
|
||||
// a block.
|
||||
dependsOn map[chainhash.Hash]struct{}
|
||||
}
|
||||
@ -1049,7 +1088,7 @@ func handleCreatedBlockTemplate(blockTemplate *BlockTemplate,
|
||||
}
|
||||
|
||||
// NewBlockTemplate returns a new block template that is ready to be solved
|
||||
// using the transactions from the passed transaction memory pool and a coinbase
|
||||
// using the transactions from the passed transaction source pool and a coinbase
|
||||
// that either pays to the passed address if it is not nil, or a coinbase that
|
||||
// is redeemable by anyone if the passed address is nil. The nil address
|
||||
// functionality is useful since there are cases such as the getblocktemplate
|
||||
@ -1070,7 +1109,7 @@ func handleCreatedBlockTemplate(blockTemplate *BlockTemplate,
|
||||
// prioritizes based on the priority (then fee per kilobyte) or the fee per
|
||||
// kilobyte (then priority) depending on whether or not the BlockPrioritySize
|
||||
// policy setting allots space for high-priority transactions. Transactions
|
||||
// which spend outputs from other transactions in the memory pool are added to a
|
||||
// which spend outputs from other transactions in the source pool are added to a
|
||||
// dependency map so they can be added to the priority queue once the
|
||||
// transactions they depend on have been included.
|
||||
//
|
||||
@ -1130,11 +1169,16 @@ func handleCreatedBlockTemplate(blockTemplate *BlockTemplate,
|
||||
//
|
||||
// This function returns nil, nil if there are not enough voters on any of
|
||||
// the current top blocks to create a new block template.
|
||||
func NewBlockTemplate(policy *miningPolicy, mempool *txMemPool,
|
||||
func NewBlockTemplate(policy *miningPolicy, server *server,
|
||||
payToAddress dcrutil.Address) (*BlockTemplate, error) {
|
||||
|
||||
blockManager := mempool.server.blockManager
|
||||
timeSource := mempool.server.timeSource
|
||||
// TODO: The mempool should be completely separated via the TxSource
|
||||
// interface so this function is fully decoupled.
|
||||
mempool := server.txMemPool
|
||||
|
||||
var txSource TxSource = server.txMemPool
|
||||
blockManager := server.blockManager
|
||||
timeSource := server.timeSource
|
||||
chainState := &blockManager.chainState
|
||||
|
||||
// Extend the most recently known best block.
|
||||
@ -1177,7 +1221,7 @@ func NewBlockTemplate(policy *miningPolicy, mempool *txMemPool,
|
||||
chainState.Unlock()
|
||||
|
||||
// Calculate the stake enabled height.
|
||||
stakeValidationHeight := mempool.server.chainParams.StakeValidationHeight
|
||||
stakeValidationHeight := server.chainParams.StakeValidationHeight
|
||||
|
||||
if nextBlockHeight >= stakeValidationHeight {
|
||||
// Obtain the entire generation of blocks stemming from this parent.
|
||||
@ -1195,7 +1239,7 @@ func NewBlockTemplate(policy *miningPolicy, mempool *txMemPool,
|
||||
minrLog.Debugf("Too few voters found on any HEAD block, " +
|
||||
"recycling a parent block to mine on")
|
||||
return handleTooFewVoters(nextBlockHeight, payToAddress,
|
||||
mempool.server.blockManager)
|
||||
server.blockManager)
|
||||
}
|
||||
minrLog.Errorf("unexpected error while sorting eligible "+
|
||||
"parents: %v", err.Error())
|
||||
@ -1233,30 +1277,29 @@ func NewBlockTemplate(policy *miningPolicy, mempool *txMemPool,
|
||||
}
|
||||
}
|
||||
|
||||
// Get the current memory pool transactions and create a priority queue
|
||||
// to hold the transactions which are ready for inclusion into a block
|
||||
// Get the current source transactions and create a priority queue to
|
||||
// hold the transactions which are ready for inclusion into a block
|
||||
// along with some priority related and fee metadata. Reserve the same
|
||||
// number of items that are in the memory pool for the priority queue.
|
||||
// Also, choose the initial sort order for the priority queue based on
|
||||
// whether or not there is an area allocated for high-priority
|
||||
// transactions.
|
||||
mempoolTxns := mempool.TxDescs()
|
||||
// number of items that are available for the priority queue. Also,
|
||||
// choose the initial sort order for the priority queue based on whether
|
||||
// or not there is an area allocated for high-priority transactions.
|
||||
sourceTxns := txSource.MiningDescs()
|
||||
sortedByFee := policy.BlockPrioritySize == 0
|
||||
lessFunc := txPQByStakeAndFeeAndThenPriority
|
||||
if sortedByFee {
|
||||
lessFunc = txPQByStakeAndFee
|
||||
}
|
||||
priorityQueue := newTxPriorityQueue(len(mempoolTxns), lessFunc)
|
||||
priorityQueue := newTxPriorityQueue(len(sourceTxns), lessFunc)
|
||||
|
||||
// Create a slice to hold the transactions to be included in the
|
||||
// generated block with reserved space. Also create a transaction
|
||||
// store to house all of the input transactions so multiple lookups
|
||||
// can be avoided.
|
||||
blockTxns := make([]*dcrutil.Tx, 0, len(mempoolTxns))
|
||||
blockTxns := make([]*dcrutil.Tx, 0, len(sourceTxns))
|
||||
blockTxStore := make(blockchain.TxStore)
|
||||
|
||||
// dependers is used to track transactions which depend on another
|
||||
// transaction in the memory pool. This, in conjunction with the
|
||||
// transaction in the source pool. This, in conjunction with the
|
||||
// dependsOn map kept with each dependent transaction helps quickly
|
||||
// determine which dependent transactions are now eligible for inclusion
|
||||
// in the block once each transaction has been included.
|
||||
@ -1268,18 +1311,18 @@ func NewBlockTemplate(policy *miningPolicy, mempool *txMemPool,
|
||||
// a transaction as it is selected for inclusion in the final block.
|
||||
// However, since the total fees aren't known yet, use a dummy value for
|
||||
// the coinbase fee which will be updated later.
|
||||
txFees := make([]int64, 0, len(mempoolTxns))
|
||||
txFees := make([]int64, 0, len(sourceTxns))
|
||||
txFeesMap := make(map[chainhash.Hash]int64)
|
||||
txSigOpCounts := make([]int64, 0, len(mempoolTxns))
|
||||
txSigOpCounts := make([]int64, 0, len(sourceTxns))
|
||||
txSigOpCountsMap := make(map[chainhash.Hash]int64)
|
||||
txFees = append(txFees, -1) // Updated once known
|
||||
|
||||
minrLog.Debugf("Considering %d mempool transactions for inclusion to "+
|
||||
"new block", len(mempoolTxns))
|
||||
minrLog.Debugf("Considering %d transactions for inclusion to new block",
|
||||
len(sourceTxns))
|
||||
treeValid := mempool.IsTxTreeValid(prevHash)
|
||||
|
||||
mempoolLoop:
|
||||
for _, txDesc := range mempoolTxns {
|
||||
for _, txDesc := range sourceTxns {
|
||||
// A block can't have more than one coinbase or contain
|
||||
// non-finalized transactions.
|
||||
tx := txDesc.Tx
|
||||
@ -1325,15 +1368,10 @@ mempoolLoop:
|
||||
continue
|
||||
}
|
||||
|
||||
// Calculate the input value age sum for the transaction. This
|
||||
// is comprised of the sum all of input amounts multiplied by
|
||||
// their respective age (number of confirmations since the
|
||||
// referenced input transaction). While doing the above, also
|
||||
// setup dependencies for any transactions which reference other
|
||||
// transactions in the mempool so they can be properly ordered
|
||||
// below.
|
||||
// Setup dependencies for any transactions which reference
|
||||
// other transactions in the mempool so they can be properly
|
||||
// ordered below.
|
||||
prioItem := &txPrioItem{tx: txDesc.Tx, txType: txDesc.Type}
|
||||
inputValueAge := float64(0.0)
|
||||
for i, txIn := range tx.MsgTx().TxIn {
|
||||
// Evaluate if this is a stakebase input or not. If it is, continue
|
||||
// without evaluation of the input.
|
||||
@ -1346,7 +1384,7 @@ mempoolLoop:
|
||||
originIndex := txIn.PreviousOutPoint.Index
|
||||
txData, exists := txStore[*originHash]
|
||||
if !exists || txData.Err != nil || txData.Tx == nil {
|
||||
if !mempool.HaveTransaction(originHash) {
|
||||
if !txSource.HaveTransaction(originHash) {
|
||||
minrLog.Tracef("Skipping tx %s because "+
|
||||
"it references tx %s which is "+
|
||||
"not available", tx.Sha,
|
||||
@ -1355,7 +1393,7 @@ mempoolLoop:
|
||||
}
|
||||
|
||||
// The transaction is referencing another
|
||||
// transaction in the memory pool, so setup an
|
||||
// transaction in the source pool, so setup an
|
||||
// ordering dependency.
|
||||
depList, exists := dependers[*originHash]
|
||||
if !exists {
|
||||
@ -1369,9 +1407,8 @@ mempoolLoop:
|
||||
}
|
||||
prioItem.dependsOn[*originHash] = struct{}{}
|
||||
|
||||
// No need to calculate or sum input value age
|
||||
// for this input since it's zero due to
|
||||
// the input age multiplier of 0.
|
||||
// Skip the check below. We already know the
|
||||
// referenced transaction is available.
|
||||
continue
|
||||
}
|
||||
|
||||
@ -1385,12 +1422,6 @@ mempoolLoop:
|
||||
originIndex, originHash)
|
||||
continue mempoolLoop
|
||||
}
|
||||
|
||||
// Sum the input value times age.
|
||||
originTxOut := txData.Tx.MsgTx().TxOut[originIndex]
|
||||
inputValue := originTxOut.Value
|
||||
inputAge := nextBlockHeight - txData.BlockHeight
|
||||
inputValueAge += float64(inputValue * inputAge)
|
||||
}
|
||||
|
||||
// Calculate the final transaction priority using the input
|
||||
@ -1469,7 +1500,7 @@ mempoolLoop:
|
||||
|
||||
// Skip if we already have too many SStx.
|
||||
if isSStx && (numSStx >=
|
||||
int(mempool.server.chainParams.MaxFreshStakePerBlock)) {
|
||||
int(server.chainParams.MaxFreshStakePerBlock)) {
|
||||
minrLog.Tracef("Skipping sstx %s because it would exceed "+
|
||||
"the max number of sstx allowed in a block", tx.Sha())
|
||||
logSkippedDeps(tx, deps)
|
||||
@ -1603,7 +1634,7 @@ mempoolLoop:
|
||||
nextBlockHeight,
|
||||
blockTxStore,
|
||||
false, // Don't check fraud proofs; missing ones are filled out below
|
||||
mempool.server.chainParams)
|
||||
server.chainParams)
|
||||
if err != nil {
|
||||
minrLog.Tracef("Skipping tx %s due to error in "+
|
||||
"CheckTransactionInputs: %v", tx.Sha(), err)
|
||||
@ -1611,7 +1642,7 @@ mempoolLoop:
|
||||
continue
|
||||
}
|
||||
err = blockchain.ValidateTransactionScripts(tx, blockTxStore,
|
||||
txscript.StandardVerifyFlags, mempool.server.sigCache)
|
||||
txscript.StandardVerifyFlags, server.sigCache)
|
||||
if err != nil {
|
||||
minrLog.Tracef("Skipping tx %s due to error in "+
|
||||
"ValidateTransactionScripts: %v", tx.Sha(), err)
|
||||
@ -1744,7 +1775,7 @@ mempoolLoop:
|
||||
}
|
||||
topBlockRegTx := topBlock.Transactions()
|
||||
|
||||
tempBlockTxns := make([]*dcrutil.Tx, 0, len(mempoolTxns))
|
||||
tempBlockTxns := make([]*dcrutil.Tx, 0, len(sourceTxns))
|
||||
for _, tx := range blockTxns {
|
||||
if tx.Tree() == dcrutil.TxTreeRegular {
|
||||
// Go through all the inputs and check to see if this mempool
|
||||
@ -1797,7 +1828,7 @@ mempoolLoop:
|
||||
}
|
||||
|
||||
// Don't let this overflow.
|
||||
if freshStake >= int(mempool.server.chainParams.MaxFreshStakePerBlock) {
|
||||
if freshStake >= int(server.chainParams.MaxFreshStakePerBlock) {
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -1854,7 +1885,7 @@ mempoolLoop:
|
||||
nextBlockHeight,
|
||||
payToAddress,
|
||||
uint16(voters),
|
||||
mempool.server.chainParams)
|
||||
server.chainParams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1926,7 +1957,7 @@ mempoolLoop:
|
||||
// If we're greater than or equal to stake validation height, scale the
|
||||
// fees according to the number of voters.
|
||||
totalFees *= int64(voters)
|
||||
totalFees /= int64(mempool.server.chainParams.TicketsPerBlock)
|
||||
totalFees /= int64(server.chainParams.TicketsPerBlock)
|
||||
|
||||
// Now that the actual transactions have been selected, update the
|
||||
// block size for the real transaction count and coinbase value with
|
||||
@ -1956,13 +1987,13 @@ mempoolLoop:
|
||||
// bit for the mempool to sync with the votes map and we end up down
|
||||
// here despite having the relevant votes available in the votes map.
|
||||
minimumVotesRequired :=
|
||||
int((mempool.server.chainParams.TicketsPerBlock / 2) + 1)
|
||||
int((server.chainParams.TicketsPerBlock / 2) + 1)
|
||||
if nextBlockHeight >= stakeValidationHeight &&
|
||||
voters < minimumVotesRequired {
|
||||
minrLog.Warnf("incongruent number of voters in mempool " +
|
||||
"vs mempool.voters; not enough voters found")
|
||||
return handleTooFewVoters(nextBlockHeight, payToAddress,
|
||||
mempool.server.blockManager)
|
||||
server.blockManager)
|
||||
}
|
||||
|
||||
// Correct transaction index fraud proofs for any transactions that
|
||||
@ -2039,7 +2070,7 @@ mempoolLoop:
|
||||
|
||||
var msgBlock wire.MsgBlock
|
||||
msgBlock.Header = wire.BlockHeader{
|
||||
Version: mempool.server.chainParams.CurrentBlockVersion,
|
||||
Version: server.chainParams.CurrentBlockVersion,
|
||||
PrevBlock: *prevHash,
|
||||
MerkleRoot: *merkles[len(merkles)-1],
|
||||
StakeRoot: *merklesStake[len(merklesStake)-1],
|
||||
@ -2077,8 +2108,8 @@ mempoolLoop:
|
||||
block.SetHeight(nextBlockHeight)
|
||||
|
||||
if err := blockchain.CheckWorklessBlockSanity(block,
|
||||
mempool.server.timeSource,
|
||||
mempool.server.chainParams); err != nil {
|
||||
server.timeSource,
|
||||
server.chainParams); err != nil {
|
||||
str := fmt.Sprintf("failed to do final check for block workless "+
|
||||
"sanity when making new block template: %v",
|
||||
err.Error())
|
||||
@ -2108,7 +2139,7 @@ mempoolLoop:
|
||||
validPayAddress: payToAddress != nil,
|
||||
}
|
||||
|
||||
return handleCreatedBlockTemplate(blockTemplate, mempool.server.blockManager)
|
||||
return handleCreatedBlockTemplate(blockTemplate, server.blockManager)
|
||||
}
|
||||
|
||||
// UpdateBlockTime updates the timestamp in the header of the passed block to
|
||||
|
||||
20
rpcserver.go
20
rpcserver.go
@ -2652,8 +2652,7 @@ func (state *gbtWorkState) updateBlockTemplate(s *rpcServer, useCoinbaseValue bo
|
||||
// block template doesn't include the coinbase, so the caller
|
||||
// will ultimately create their own coinbase which pays to the
|
||||
// appropriate address(es).
|
||||
blkTemplate, err := NewBlockTemplate(s.policy, s.server.txMemPool,
|
||||
payAddr)
|
||||
blkTemplate, err := NewBlockTemplate(s.policy, s.server, payAddr)
|
||||
if err != nil {
|
||||
return internalRPCError("Failed to create new block "+
|
||||
"template: "+err.Error(), "")
|
||||
@ -3610,15 +3609,15 @@ func handleGetInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (in
|
||||
|
||||
// handleGetMempoolInfo implements the getmempoolinfo command.
|
||||
func handleGetMempoolInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||
txD := s.server.txMemPool.TxDescs()
|
||||
mempoolTxns := s.server.txMemPool.TxDescs()
|
||||
|
||||
var numBytes int64
|
||||
for _, desc := range txD {
|
||||
numBytes += int64(desc.Tx.MsgTx().SerializeSize())
|
||||
for _, txD := range mempoolTxns {
|
||||
numBytes += int64(txD.Tx.MsgTx().SerializeSize())
|
||||
}
|
||||
|
||||
ret := &dcrjson.GetMempoolInfoResult{
|
||||
Size: int64(len(txD)),
|
||||
Size: int64(len(mempoolTxns)),
|
||||
Bytes: numBytes,
|
||||
}
|
||||
|
||||
@ -3874,7 +3873,7 @@ func handleGetRawMempool(s *rpcServer, cmd interface{}, closeChan <-chan struct{
|
||||
}
|
||||
|
||||
mpd := &dcrjson.GetRawMempoolVerboseResult{
|
||||
Size: int32(desc.Tx.MsgTx().SerializeSize()),
|
||||
Size: int32(tx.MsgTx().SerializeSize()),
|
||||
Fee: dcrutil.Amount(desc.Fee).ToCoin(),
|
||||
Time: desc.Added.Unix(),
|
||||
Height: desc.Height,
|
||||
@ -3882,7 +3881,7 @@ func handleGetRawMempool(s *rpcServer, cmd interface{}, closeChan <-chan struct{
|
||||
CurrentPriority: currentPriority,
|
||||
Depends: make([]string, 0),
|
||||
}
|
||||
for _, txIn := range desc.Tx.MsgTx().TxIn {
|
||||
for _, txIn := range tx.MsgTx().TxIn {
|
||||
hash := &txIn.PreviousOutPoint.Hash
|
||||
if s.server.txMemPool.haveTransaction(hash) {
|
||||
mpd.Depends = append(mpd.Depends,
|
||||
@ -3890,7 +3889,7 @@ func handleGetRawMempool(s *rpcServer, cmd interface{}, closeChan <-chan struct{
|
||||
}
|
||||
}
|
||||
|
||||
result[desc.Tx.Sha().String()] = mpd
|
||||
result[tx.Sha().String()] = mpd
|
||||
}
|
||||
|
||||
return result, nil
|
||||
@ -4267,8 +4266,7 @@ func handleGetWorkRequest(s *rpcServer) (interface{}, error) {
|
||||
// Choose a payment address at random.
|
||||
payToAddr := cfg.miningAddrs[rand.Intn(len(cfg.miningAddrs))]
|
||||
|
||||
template, err := NewBlockTemplate(s.policy, s.server.txMemPool,
|
||||
payToAddr)
|
||||
template, err := NewBlockTemplate(s.policy, s.server, payToAddr)
|
||||
if err != nil {
|
||||
context := "Failed to create new block template"
|
||||
return nil, internalRPCError(err.Error(), context)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user