Changeset View
Standalone View
src/miner.h
Show First 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
}; | }; | ||||
// Container for tracking updates to ancestor feerate as we include (parent) | // Container for tracking updates to ancestor feerate as we include (parent) | ||||
// transactions in a block | // transactions in a block | ||||
struct CTxMemPoolModifiedEntry { | struct CTxMemPoolModifiedEntry { | ||||
explicit CTxMemPoolModifiedEntry(CTxMemPool::txiter entry) { | explicit CTxMemPoolModifiedEntry(CTxMemPool::txiter entry) { | ||||
iter = entry; | iter = entry; | ||||
nSizeWithAncestors = entry->GetSizeWithAncestors(); | nSizeWithAncestors = entry->GetSizeWithAncestors(); | ||||
nVirtualSizeWithAncestors = entry->GetVirtualSizeWithAncestors(); | |||||
nModFeesWithAncestors = entry->GetModFeesWithAncestors(); | nModFeesWithAncestors = entry->GetModFeesWithAncestors(); | ||||
nSigOpCountWithAncestors = entry->GetSigOpCountWithAncestors(); | nSigOpCountWithAncestors = entry->GetSigOpCountWithAncestors(); | ||||
} | } | ||||
Amount GetModifiedFee() const { return iter->GetModifiedFee(); } | Amount GetModifiedFee() const { return iter->GetModifiedFee(); } | ||||
uint64_t GetSizeWithAncestors() const { return nSizeWithAncestors; } | uint64_t GetSizeWithAncestors() const { return nSizeWithAncestors; } | ||||
uint64_t GetVirtualSizeWithAncestors() const { | |||||
return nVirtualSizeWithAncestors; | |||||
deadalnix: This could be computed on the fly, but more importantly, I don't understand what's the play… | |||||
markblundebergAuthorUnsubmitted Done Inline ActionsWe could indeed compute VirtualSize(sum(sizes), sum(sigops)) quickly on the fly, but that's not the same thing as sum(Virtualsize(size, sigop)) since it's not a strictly linear function (the std::max is a nonlinearity). So it's not just caching vs noncaching, but also a difference in behaviour. As I mentioned to you privately I do actually think the former is more accurate in some ways, but it does result in some weirdness: the package virtualsize may in some cases not actually increase when more transactions are added, if the ancestors are dense in sigops (e.g., p2sh -> p2pkh transactions) and the new child tx has 0 sigops (e.g., a p2pkh -> p2sh transaction). In fact if VirtualSize is defined more weirdly than the current definition, it could even decrease upon adding a tx. Although weird, I can't actually see any issues resulting from this, provided we only use it for priority. markblundeberg: We could indeed compute `VirtualSize(sum(sizes), sum(sigops))` quickly on the fly, but that's… | |||||
} | |||||
Amount GetModFeesWithAncestors() const { return nModFeesWithAncestors; } | Amount GetModFeesWithAncestors() const { return nModFeesWithAncestors; } | ||||
size_t GetTxSize() const { return iter->GetTxSize(); } | size_t GetTxSize() const { return iter->GetTxSize(); } | ||||
size_t GetTxVirtualSize() const { return iter->GetTxVirtualSize(); } | |||||
const CTransaction &GetTx() const { return iter->GetTx(); } | const CTransaction &GetTx() const { return iter->GetTx(); } | ||||
CTxMemPool::txiter iter; | CTxMemPool::txiter iter; | ||||
uint64_t nSizeWithAncestors; | uint64_t nSizeWithAncestors; | ||||
uint64_t nVirtualSizeWithAncestors; | |||||
Amount nModFeesWithAncestors; | Amount nModFeesWithAncestors; | ||||
int64_t nSigOpCountWithAncestors; | int64_t nSigOpCountWithAncestors; | ||||
}; | }; | ||||
/** | /** | ||||
* Comparator for CTxMemPool::txiter objects. | * Comparator for CTxMemPool::txiter objects. | ||||
* It simply compares the internal memory address of the CTxMemPoolEntry object | * It simply compares the internal memory address of the CTxMemPoolEntry object | ||||
* pointed to. This means it has no meaning, and is only useful for using them | * pointed to. This means it has no meaning, and is only useful for using them | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | typedef indexed_modified_transaction_set::index<ancestor_score>::type::iterator | ||||
modtxscoreiter; | modtxscoreiter; | ||||
struct update_for_parent_inclusion { | struct update_for_parent_inclusion { | ||||
explicit update_for_parent_inclusion(CTxMemPool::txiter it) : iter(it) {} | explicit update_for_parent_inclusion(CTxMemPool::txiter it) : iter(it) {} | ||||
void operator()(CTxMemPoolModifiedEntry &e) { | void operator()(CTxMemPoolModifiedEntry &e) { | ||||
e.nModFeesWithAncestors -= iter->GetFee(); | e.nModFeesWithAncestors -= iter->GetFee(); | ||||
e.nSizeWithAncestors -= iter->GetTxSize(); | e.nSizeWithAncestors -= iter->GetTxSize(); | ||||
e.nVirtualSizeWithAncestors -= iter->GetTxVirtualSize(); | |||||
e.nSigOpCountWithAncestors -= iter->GetSigOpCount(); | e.nSigOpCountWithAncestors -= iter->GetSigOpCount(); | ||||
} | } | ||||
CTxMemPool::txiter iter; | CTxMemPool::txiter iter; | ||||
}; | }; | ||||
/** Generate a new block, without valid proof-of-work */ | /** Generate a new block, without valid proof-of-work */ | ||||
class BlockAssembler { | class BlockAssembler { | ||||
▲ Show 20 Lines • Show All 99 Lines • Show Last 20 Lines |
This could be computed on the fly, but more importantly, I don't understand what's the play here? It seems to me like this is to be used to compute fee per byte and use that to select the best possible candidates for inclusion, but you'll still have to count sigops/size to make sure it doesn't go over.
Caching infos is usually a bad idea, because then you get cache coherency problems. If it is cheap to compute, then it's probably best to do so.