Skip to content

Commit a87589a

Browse files
committed
Introduce waitFeesChanged() mining interface
1 parent f3c74c4 commit a87589a

File tree

3 files changed

+46
-4
lines changed

3 files changed

+46
-4
lines changed

src/interfaces/mining.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,18 @@ class Mining
7171
*/
7272
virtual BlockRef waitTipChanged(uint256 current_tip, MillisecondsDouble timeout = MillisecondsDouble::max()) = 0;
7373

74+
/**
75+
* Waits for fees in the next block to rise, a new tip or the timeout.
76+
*
77+
* @param[in] current_tip block hash that the most recent template builds on
78+
* @param[in] fee_threshold how far total fees for the next block should rise (currently ignored)
79+
* @param[in] options options for creating the block, should match those
80+
* passed to createNewBlock (currently ignored)
81+
*
82+
* @returns true if fees increased, false if a new tip arrives or the timeout occurs
83+
*/
84+
virtual bool waitFeesChanged(uint256 current_tip, CAmount fee_threshold, const node::BlockCreateOptions& options = {}, MillisecondsDouble timeout = MillisecondsDouble::max()) = 0;
85+
7486
/**
7587
* Construct a new block template
7688
*

src/ipc/capnp/mining.capnp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@ interface Mining $Proxy.wrap("interfaces::Mining") {
1717
isInitialBlockDownload @1 (context :Proxy.Context) -> (result: Bool);
1818
getTip @2 (context :Proxy.Context) -> (result: Common.BlockRef, hasResult: Bool);
1919
waitTipChanged @3 (context :Proxy.Context, currentTip: Data, timeout: Float64) -> (result: Common.BlockRef);
20-
createNewBlock @4 (scriptPubKey: Data, options: BlockCreateOptions) -> (result: BlockTemplate);
21-
processNewBlock @5 (context :Proxy.Context, block: Data) -> (newBlock: Bool, result: Bool);
22-
getTransactionsUpdated @6 (context :Proxy.Context) -> (result: UInt32);
23-
testBlockValidity @7 (context :Proxy.Context, block: Data, checkMerkleRoot: Bool) -> (state: BlockValidationState, result: Bool);
20+
waitFeesChanged @4 (context :Proxy.Context, currentTip: Data, feeThreshold: Int64, options: BlockCreateOptions, timeout: Float64) -> (result: Bool);
21+
createNewBlock @5 (scriptPubKey: Data, options: BlockCreateOptions) -> (result: BlockTemplate);
22+
processNewBlock @6 (context :Proxy.Context, block: Data) -> (newBlock: Bool, result: Bool);
23+
getTransactionsUpdated @7 (context :Proxy.Context) -> (result: UInt32);
24+
testBlockValidity @8 (context :Proxy.Context, block: Data, checkMerkleRoot: Bool) -> (state: BlockValidationState, result: Bool);
2425
}
2526

2627
interface BlockTemplate $Proxy.wrap("interfaces::BlockTemplate") {

src/node/interfaces.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,35 @@ class MinerImpl : public Mining
957957
return BlockRef{chainman().ActiveChain().Tip()->GetBlockHash(), chainman().ActiveChain().Tip()->nHeight};
958958
}
959959

960+
bool waitFeesChanged(uint256 current_tip, CAmount fee_threshold, const BlockCreateOptions& options, MillisecondsDouble timeout) override
961+
{
962+
if (timeout > std::chrono::years{100}) timeout = std::chrono::years{100}; // Upper bound to avoid UB in std::chrono
963+
auto now{std::chrono::steady_clock::now()};
964+
const auto deadline = now + timeout;
965+
const MillisecondsDouble tick{1000};
966+
967+
unsigned int last_mempool_update{context()->mempool->GetTransactionsUpdated()};
968+
969+
BlockAssembler::Options assemble_options{options};
970+
ApplyArgsManOptions(*Assert(m_node.args), assemble_options);
971+
972+
while (!chainman().m_interrupt) {
973+
now = std::chrono::steady_clock::now();
974+
if (now >= deadline) break;
975+
976+
if (getTip().value().hash != current_tip) {
977+
return false;
978+
}
979+
980+
// TODO: when cluster mempool is available, actually calculate
981+
// fees for the next block. This is currently too expensive.
982+
if (context()->mempool->GetTransactionsUpdated() > last_mempool_update) return true;
983+
984+
std::this_thread::sleep_until(std::min(deadline, now + tick));
985+
}
986+
return false;
987+
}
988+
960989
bool processNewBlock(const std::shared_ptr<const CBlock>& block, bool* new_block) override
961990
{
962991
return chainman().ProcessNewBlock(block, /*force_processing=*/true, /*min_pow_checked=*/true, /*new_block=*/new_block);

0 commit comments

Comments
 (0)