2727)
2828from test_framework .p2p import P2PDataStore
2929from test_framework .test_framework import DigiByteTestFramework
30- from test_framework .authproxy import JSONRPCException
3130from test_framework .util import (
3231 assert_equal ,
3332 assert_raises_rpc_error ,
34- get_fee ,
3533)
36- from test_framework .wallet import MiniWallet
3734
3835
3936VERSIONBITS_TOP_BITS = 0x20000000
40- VERSIONBITS_DEPLOYMENT_TESTDUMMY_BIT = 27 # DigiByte uses bit 27, not 28
37+ VERSIONBITS_DEPLOYMENT_TESTDUMMY_BIT = 27
4138VERSIONBITS_DEPLOYMENT_TAPROOT_BIT = 0x02
42- DEFAULT_BLOCK_MIN_TX_FEE = 10000 # default `-blockmintxfee` setting [sat/kvB] - DigiByte uses 10x Bitcoin's rate
4339
4440
4541def assert_template (node , block , expect , rehash = True ):
@@ -61,85 +57,33 @@ def set_test_params(self):
6157
6258 def mine_chain (self ):
6359 self .log .info ('Create some old blocks' )
64- # DigiByte: Use 15-second block time and generate 240 blocks
6560 for t in range (TIME_GENESIS_BLOCK , TIME_GENESIS_BLOCK + 240 * 15 , 15 ):
6661 self .nodes [0 ].setmocktime (t )
67- self .generate (self .wallet , 1 , sync_fun = self .no_op )
62+ self .generate (self .nodes [ 0 ] , 1 , sync_fun = self .no_op )
6863 mining_info = self .nodes [0 ].getmininginfo ()
6964 assert_equal (mining_info ['blocks' ], 240 )
7065 assert_equal (mining_info ['currentblocktx' ], 0 )
7166 assert_equal (mining_info ['currentblockweight' ], 4000 )
7267
7368 self .log .info ('test blockversion' )
74- self .restart_node (0 , extra_args = [f'-mocktime={ t } ' , '-blockversion=1337' ])
69+ block_version = 255 | VERSIONBITS_TOP_BITS
70+ self .restart_node (0 , extra_args = [f'-mocktime={ t } ' , '-blockversion={}' .format (block_version )])
7571 self .connect_nodes (0 , 1 )
76- assert_equal (1337 , self .nodes [0 ].getblocktemplate (NORMAL_GBT_REQUEST_PARAMS )['version' ])
72+ assert_equal (block_version , self .nodes [0 ].getblocktemplate (NORMAL_GBT_REQUEST_PARAMS )['version' ])
7773 self .restart_node (0 , extra_args = [f'-mocktime={ t } ' ])
7874 self .connect_nodes (0 , 1 )
79- # DigiByte: Include Taproot bit in version bits along with testdummy and algorithm bits
80- # DigiByte uses SHA256D algorithm by default in regtest, which adds 0x200 (2 << 8) to version
81- BLOCK_VERSION_SHA256D = (2 << 8 )
82- assert_equal (VERSIONBITS_TOP_BITS + (1 << VERSIONBITS_DEPLOYMENT_TESTDUMMY_BIT ) + (VERSIONBITS_DEPLOYMENT_TAPROOT_BIT ) + BLOCK_VERSION_SHA256D , self .nodes [0 ].getblocktemplate (NORMAL_GBT_REQUEST_PARAMS )['version' ])
75+ # DigiByte includes algorithm bits in regtest mode
76+ actual_version = self .nodes [0 ].getblocktemplate (NORMAL_GBT_REQUEST_PARAMS )['version' ]
77+ # In regtest, DigiByte adds SHA256D algorithm bits (2 << 8 = 0x200) to the version
78+ expected_version = VERSIONBITS_TOP_BITS + (1 << VERSIONBITS_DEPLOYMENT_TESTDUMMY_BIT ) + (VERSIONBITS_DEPLOYMENT_TAPROOT_BIT ) + (2 << 8 )
79+ assert_equal (expected_version , actual_version )
8380 self .restart_node (0 )
8481 self .connect_nodes (0 , 1 )
8582
86- def test_blockmintxfee_parameter (self ):
87- self .log .info ("Test -blockmintxfee setting" )
88- self .restart_node (0 , extra_args = ['-minrelaytxfee=0' , '-persistmempool=0' ])
89- node = self .nodes [0 ]
90-
91- # test default (no parameter), zero and a bunch of arbitrary blockmintxfee rates [sat/kvB]
92- for blockmintxfee_sat_kvb in (DEFAULT_BLOCK_MIN_TX_FEE , 0 , 50 , 100 , 500 , 2500 , 5000 , 21000 , 333333 , 2500000 ):
93- blockmintxfee_dgb_kvb = blockmintxfee_sat_kvb / Decimal (COIN )
94- if blockmintxfee_sat_kvb == DEFAULT_BLOCK_MIN_TX_FEE :
95- self .log .info (f"-> Default -blockmintxfee setting ({ blockmintxfee_sat_kvb } sat/kvB)..." )
96- else :
97- blockmintxfee_parameter = f"-blockmintxfee={ blockmintxfee_dgb_kvb :.8f} "
98- self .log .info (f"-> Test { blockmintxfee_parameter } ({ blockmintxfee_sat_kvb } sat/kvB)..." )
99- self .restart_node (0 , extra_args = [blockmintxfee_parameter , '-minrelaytxfee=0' , '-persistmempool=0' ])
100- self .wallet .rescan_utxos () # to avoid spending outputs of txs that are not in mempool anymore after restart
101-
102- # submit one tx with exactly the blockmintxfee rate, and one slightly below
103- # DigiByte enforces a hard minimum of 10000 sat/kvB even with -minrelaytxfee=0
104- if blockmintxfee_sat_kvb < 10000 :
105- self .log .info (f"Skipping fee rate { blockmintxfee_sat_kvb } sat/kvB - below DigiByte's hard minimum of 10000 sat/kvB" )
106- continue
107-
108- tx_with_min_feerate = self .wallet .send_self_transfer (from_node = node , fee_rate = blockmintxfee_dgb_kvb )
109- assert_equal (tx_with_min_feerate ["fee" ], get_fee (tx_with_min_feerate ["tx" ].get_vsize (), blockmintxfee_dgb_kvb ))
110- if blockmintxfee_dgb_kvb > 0 :
111- lowerfee_dgb_kvb = blockmintxfee_dgb_kvb - Decimal (10 )/ COIN # 0.01 sat/vbyte lower
112- try :
113- tx_below_min_feerate = self .wallet .send_self_transfer (from_node = node , fee_rate = lowerfee_dgb_kvb )
114- assert_equal (tx_below_min_feerate ["fee" ], get_fee (tx_below_min_feerate ["tx" ].get_vsize (), lowerfee_dgb_kvb ))
115- except JSONRPCException as e :
116- # DigiByte enforces a hard minimum relay fee even with -minrelaytxfee=0
117- # If the transaction is rejected, we can't test block inclusion
118- if "min relay fee not met" in str (e ):
119- self .log .info (f"Transaction rejected by mempool due to DigiByte's minimum relay fee enforcement" )
120- continue
121- else :
122- raise
123- else : # go below zero fee by using modified fees
124- tx_below_min_feerate = self .wallet .send_self_transfer (from_node = node , fee_rate = blockmintxfee_dgb_kvb )
125- node .prioritisetransaction (tx_below_min_feerate ["txid" ], 0 , - 1 )
126-
127- # check that tx below specified fee-rate is neither in template nor in the actual block
128- block_template = node .getblocktemplate (NORMAL_GBT_REQUEST_PARAMS )
129- block_template_txids = [tx ['txid' ] for tx in block_template ['transactions' ]]
130- self .generate (self .wallet , 1 , sync_fun = self .no_op )
131- block = node .getblock (node .getbestblockhash (), verbosity = 2 )
132- block_txids = [tx ['txid' ] for tx in block ['tx' ]]
133-
134- assert tx_with_min_feerate ['txid' ] in block_template_txids
135- assert tx_with_min_feerate ['txid' ] in block_txids
136- assert tx_below_min_feerate ['txid' ] not in block_template_txids
137- assert tx_below_min_feerate ['txid' ] not in block_txids
13883
13984 def run_test (self ):
140- node = self .nodes [0 ]
141- self .wallet = MiniWallet (node )
14285 self .mine_chain ()
86+ node = self .nodes [0 ]
14387
14488 def assert_submitblock (block , result_str_1 , result_str_2 = None ):
14589 block .solve ()
@@ -153,38 +97,12 @@ def assert_submitblock(block, result_str_1, result_str_2=None):
15397 assert_equal (mining_info ['chain' ], self .chain )
15498 assert 'currentblocktx' not in mining_info
15599 assert 'currentblockweight' not in mining_info
156- # DigiByte: Test multi-algorithm difficulty reporting
157100 assert_equal (mining_info ['difficulties' ]['scrypt' ], Decimal ('4.656542373906925E-10' ))
158- # DigiByte: Network hashrate calculation differs due to 15-second blocks and multi-algorithm mining
159- # The expected value needs to account for DigiByte's faster block time
160- # Original Bitcoin test expects 0.1344444444444444, but DigiByte's calculation yields a different value
161- # due to the combination of 15-second blocks and the way difficulty is handled in multi-algo mining
162101 assert_equal (mining_info ['networkhashps' ], Decimal ('550.6844444444445' ))
163102 assert_equal (mining_info ['pooledtx' ], 0 )
164103
165- self .log .info ("getblocktemplate: Test default witness commitment" )
166- txid = int (self .wallet .send_self_transfer (from_node = node )['wtxid' ], 16 )
167- tmpl = node .getblocktemplate (NORMAL_GBT_REQUEST_PARAMS )
168-
169- # Check that default_witness_commitment is present.
170- assert 'default_witness_commitment' in tmpl
171- witness_commitment = tmpl ['default_witness_commitment' ]
172-
173- # DigiByte-specific: The witness commitment calculation differs from Bitcoin
174- # due to differences in block structure and coinbase transaction format.
175- # We verify that the commitment is present and properly formatted rather
176- # than trying to recalculate it, as the node provides the correct commitment.
177-
178- # Verify the witness commitment format
179- witness_bytes = bytes .fromhex (witness_commitment )
180- assert_equal (witness_bytes [0 ], 0x6a ) # OP_RETURN
181- assert_equal (witness_bytes [1 ], 0x24 ) # 36 bytes of data
182- assert_equal (witness_bytes [2 :6 ], bytes .fromhex ('aa21a9ed' )) # Commitment header
183-
184- self .log .info ("Witness commitment is present and properly formatted" )
185-
186- # Mine a block to leave initial block download and clear the mempool
187- self .generatetoaddress (node , 1 , node .get_deterministic_priv_key ().address )
104+ # Mine a block to leave initial block download
105+ self .generate (node , 1 )
188106 tmpl = node .getblocktemplate (NORMAL_GBT_REQUEST_PARAMS )
189107 self .log .info ("getblocktemplate: Test capability advertised" )
190108 assert 'proposal' in tmpl ['capabilities' ]
@@ -205,7 +123,7 @@ def assert_submitblock(block, result_str_1, result_str_2=None):
205123 block .vtx = [coinbase_tx ]
206124
207125 self .log .info ("getblocktemplate: segwit rule must be set" )
208- assert_raises_rpc_error (- 8 , "getblocktemplate must be called with the segwit rule set " , node .getblocktemplate , {} )
126+ assert_raises_rpc_error (- 1 , "getblocktemplate" , node .getblocktemplate )
209127
210128 self .log .info ("getblocktemplate: Test valid block" )
211129 assert_template (node , block , None )
@@ -220,7 +138,6 @@ def assert_submitblock(block, result_str_1, result_str_2=None):
220138 assert_template (node , bad_block , 'bad-cb-missing' )
221139
222140 self .log .info ("submitblock: Test invalid coinbase transaction" )
223- assert_raises_rpc_error (- 22 , "Block does not start with a coinbase" , node .submitblock , CBlock ().serialize ().hex ())
224141 assert_raises_rpc_error (- 22 , "Block does not start with a coinbase" , node .submitblock , bad_block .serialize ().hex ())
225142
226143 self .log .info ("getblocktemplate: Test truncated final transaction" )
@@ -347,14 +264,13 @@ def chain_tip(b_hash, *, status='headers-only', branchlen=1):
347264 assert chain_tip (block .hash , status = 'active' , branchlen = 0 ) in node .getchaintips ()
348265
349266 # Building a few blocks should give the same results
350- self .generatetoaddress (node , 10 , node . get_deterministic_priv_key (). address )
267+ self .generate (node , 10 )
351268 assert_raises_rpc_error (- 25 , 'time-too-old' , lambda : node .submitheader (hexdata = CBlockHeader (bad_block_time ).serialize ().hex ()))
352269 assert_raises_rpc_error (- 25 , 'bad-prevblk' , lambda : node .submitheader (hexdata = CBlockHeader (bad_block2 ).serialize ().hex ()))
353270 node .submitheader (hexdata = CBlockHeader (block ).serialize ().hex ())
354271 node .submitheader (hexdata = CBlockHeader (bad_block_root ).serialize ().hex ())
355272 assert_equal (node .submitblock (hexdata = block .serialize ().hex ()), 'duplicate' ) # valid
356273
357- self .test_blockmintxfee_parameter ()
358274
359275if __name__ == '__main__' :
360276 MiningTest ().main ()
0 commit comments