@@ -8,6 +8,7 @@ use crate::error::RpcError;
88use crate :: handlers:: { ensure_no_params, params_array, required_str} ;
99
1010const NETWORK_HASHPS_WINDOW : u32 = 120 ;
11+ const MAX_BLOCK_WEIGHT : u64 = 4_000_000 ;
1112
1213pub ( crate ) fn getblocktemplate ( ctx : & Arc < Context > , params : & Value ) -> Result < Value , RpcError > {
1314 if !params. is_null ( ) {
@@ -51,6 +52,7 @@ pub(crate) fn getblocktemplate(ctx: &Arc<Context>, params: &Value) -> Result<Val
5152
5253pub ( crate ) fn getmininginfo ( ctx : & Arc < Context > , params : & Value ) -> Result < Value , RpcError > {
5354 ensure_no_params ( params) ?;
55+ let ( current_block_weight, current_block_tx) = estimate_current_block ( ctx) ;
5456
5557 let blocks = ctx. applied_height ( ) ;
5658 let pooledtx = ctx. mempool . read ( ) . stats ( ) . txs ;
@@ -71,8 +73,8 @@ pub(crate) fn getmininginfo(ctx: &Arc<Context>, params: &Value) -> Result<Value,
7173
7274 Ok ( json ! ( {
7375 "blocks" : blocks,
74- "currentblockweight" : 0_u64 ,
75- "currentblocktx" : 0_u64 ,
76+ "currentblockweight" : current_block_weight ,
77+ "currentblocktx" : current_block_tx ,
7678 "difficulty" : difficulty,
7779 "networkhashps" : estimate_network_hashps( ctx) ,
7880 "pooledtx" : pooledtx,
@@ -81,6 +83,30 @@ pub(crate) fn getmininginfo(ctx: &Arc<Context>, params: &Value) -> Result<Value,
8183 } ) )
8284}
8385
86+ fn estimate_current_block ( ctx : & Context ) -> ( u64 , u64 ) {
87+ let pool = ctx. mempool . read ( ) ;
88+ let mut candidates: Vec < ( u64 , u64 ) > = Vec :: with_capacity ( pool. entries . len ( ) ) ;
89+ for ( _id, entry) in & pool. entries {
90+ let weight = u64:: from ( entry. vsize ) . saturating_mul ( 4 ) ;
91+ candidates. push ( ( entry. fee_rate , weight) ) ;
92+ }
93+
94+ candidates. sort_by ( |a, b| b. 0 . cmp ( & a. 0 ) ) ;
95+
96+ let mut total_weight: u64 = 0 ;
97+ let mut tx_count: u64 = 0 ;
98+ for ( _rate, weight) in candidates {
99+ let next = total_weight. saturating_add ( weight) ;
100+ if next > MAX_BLOCK_WEIGHT {
101+ break ;
102+ }
103+ total_weight = next;
104+ tx_count = tx_count. saturating_add ( 1 ) ;
105+ }
106+
107+ ( total_weight, tx_count)
108+ }
109+
84110fn estimate_network_hashps ( ctx : & Context ) -> f64 {
85111 let tree = ctx. block_tree . read ( ) ;
86112 let Some ( tip_snapshot) = ctx. applied_tip . load_full ( ) else {
@@ -215,6 +241,43 @@ mod getmininginfo_tests {
215241 assert_eq ! ( pooledtx, 0 ) ;
216242 }
217243
244+ #[ test]
245+ fn getmininginfo_currentblockweight_reflects_mempool_when_populated ( ) {
246+ use bitcoin_rs_mempool:: MempoolEntry ;
247+
248+ let ctx = Arc :: new ( Context :: new ( ) ) ;
249+ {
250+ let mut pool = ctx. mempool . write ( ) ;
251+ let tx = bitcoin:: Transaction {
252+ version : bitcoin:: transaction:: Version ( 2 ) ,
253+ lock_time : bitcoin:: absolute:: LockTime :: ZERO ,
254+ input : Vec :: new ( ) ,
255+ output : Vec :: new ( ) ,
256+ } ;
257+ let entry = MempoolEntry :: new ( Arc :: new ( tx) , 250 , 5_000 , 1 , 7 ) ;
258+ pool. insert_entry ( entry)
259+ . unwrap_or_else ( |err| panic ! ( "insert_entry failed: {err}" ) ) ;
260+ }
261+
262+ let result = getmininginfo ( & ctx, & json ! ( [ ] ) )
263+ . unwrap_or_else ( |err| panic ! ( "getmininginfo failed: {err}" ) ) ;
264+ let Some ( weight) = result
265+ . get ( "currentblockweight" )
266+ . and_then ( JsonValueTrait :: as_u64)
267+ else {
268+ panic ! ( "currentblockweight missing: {result:?}" ) ;
269+ } ;
270+ let Some ( tx_count) = result
271+ . get ( "currentblocktx" )
272+ . and_then ( JsonValueTrait :: as_u64)
273+ else {
274+ panic ! ( "currentblocktx missing: {result:?}" ) ;
275+ } ;
276+
277+ assert_eq ! ( weight, 1_000 ) ;
278+ assert_eq ! ( tx_count, 1 ) ;
279+ }
280+
218281 #[ test]
219282 fn getmininginfo_networkhashps_zero_when_no_applied_tip ( ) {
220283 let ctx = Arc :: new ( Context :: new ( ) ) ;
0 commit comments