Changeset View
Changeset View
Standalone View
Standalone View
contrib/devtools/chainparams/test_make_chainparams.py
#!/usr/bin/env python3 | #!/usr/bin/env python3 | ||||
# Copyright (c) 2019 The Bitcoin developers | # Copyright (c) 2019 The Bitcoin developers | ||||
# Distributed under the MIT software license, see the accompanying | # Distributed under the MIT software license, see the accompanying | ||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php. | # file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
import unittest | import unittest | ||||
from make_chainparams import main as GenerateChainParams | from make_chainparams import main as GenerateChainParams | ||||
class MockRPC: | class MockRPC: | ||||
def __init__(self, test, chain, numBlocks, | def __init__(self, test, chain, numBlocks, expectedBlock, | ||||
expectedBlock, blockHash, chainWork): | blockHash, chainWork, blockchainSize, chainstateSize): | ||||
self.test = test | self.test = test | ||||
self.chain = chain | self.chain = chain | ||||
self.numBlocks = numBlocks | self.numBlocks = numBlocks | ||||
self.expectedBlock = expectedBlock | self.expectedBlock = expectedBlock | ||||
self.blockchainSize = blockchainSize | |||||
self.blockHash = blockHash | self.blockHash = blockHash | ||||
self.chainstateSize = chainstateSize | |||||
self.chainWork = chainWork | self.chainWork = chainWork | ||||
def getblockchaininfo(self): | def getblockchaininfo(self): | ||||
return { | return { | ||||
"chain": self.chain, | "chain": self.chain, | ||||
"blocks": self.numBlocks, | "blocks": self.numBlocks, | ||||
"headers": self.numBlocks, | "headers": self.numBlocks, | ||||
"bestblockhash": "0000000000000000039c96605d7fca74a5e185ea5634198346e9e07fd235b666", | "bestblockhash": "0000000000000000039c96605d7fca74a5e185ea5634198346e9e07fd235b666", | ||||
"difficulty": 274412074285.6605, | "difficulty": 274412074285.6605, | ||||
"mediantime": 1562168718, | "mediantime": 1562168718, | ||||
"verificationprogress": 0.9999958005632363, | "verificationprogress": 0.9999958005632363, | ||||
"initialblockdownload": False, | "initialblockdownload": False, | ||||
"chainwork": self.chainWork, | "chainwork": self.chainWork, | ||||
"size_on_disk": 952031444, | "size_on_disk": self.blockchainSize, | ||||
"pruned": True, | "pruned": True, | ||||
"pruneheight": 582974, | "pruneheight": 582974, | ||||
"automatic_pruning": True, | "automatic_pruning": True, | ||||
"prune_target_size": 1048576000, | "prune_target_size": 1048576000, | ||||
} | } | ||||
def getblockhash(self, block): | def getblockhash(self, block): | ||||
# Tests should always request the right block height. Even though a | # Tests should always request the right block height. Even though a | ||||
Show All 20 Lines | def getblockheader(self, blockHash): | ||||
"mediantime": 1563208994, | "mediantime": 1563208994, | ||||
"nonce": 3501699724, | "nonce": 3501699724, | ||||
"bits": "18040cd6", | "bits": "18040cd6", | ||||
"difficulty": 271470800310.0635, | "difficulty": 271470800310.0635, | ||||
"chainwork": "000000000000000000000000000000000000000000f4c5e639fa012518a48a57", | "chainwork": "000000000000000000000000000000000000000000f4c5e639fa012518a48a57", | ||||
"previousblockhash": "00000000000000000307b45e4a6cf8d49e70b9012ea1d72a5ce334a4213f66bd", | "previousblockhash": "00000000000000000307b45e4a6cf8d49e70b9012ea1d72a5ce334a4213f66bd", | ||||
} | } | ||||
def gettxoutsetinfo(self): | |||||
return { | |||||
"height": 636013, | |||||
"bestblock": "00000000000000000250a6ab6c6c4778086807f5b39910a8c108efa511282280", | |||||
"transactions": 19360831, | |||||
"txouts": 42145889, | |||||
"bogosize": 3187119531, | |||||
"hash_serialized": "1b1cc457771e8b6f849ac21c4da43ebe5c614df9e61a943252978437ad774ce5", | |||||
"disk_size": self.chainstateSize, | |||||
"total_amount": 18412423.42452419, | |||||
} | |||||
class MockFailRPC(MockRPC): | class MockFailRPC(MockRPC): | ||||
# Provides a fail counter to fail after the Nth RPC command | # Provides a fail counter to fail after the Nth RPC command | ||||
def __init__(self, test, chain, numBlocks, expectedBlock, | def __init__(self, test, chain, numBlocks, expectedBlock, blockHash, | ||||
blockHash, chainWork, failCounter): | chainWork, blockchainSize, chainstateSize, failCounter): | ||||
super().__init__(test, chain, numBlocks, expectedBlock, blockHash, chainWork) | super().__init__( | ||||
test, | |||||
chain, | |||||
numBlocks, | |||||
expectedBlock, | |||||
blockHash, | |||||
chainWork, | |||||
blockchainSize, | |||||
chainstateSize) | |||||
self.failCounter = failCounter | self.failCounter = failCounter | ||||
def checkFailCounter(self): | def checkFailCounter(self): | ||||
self.failCounter -= 1 | self.failCounter -= 1 | ||||
if self.failCounter < 0: | if self.failCounter < 0: | ||||
raise Exception("""error code: -99 | raise Exception("""error code: -99 | ||||
error message: | error message: | ||||
mock error""") | mock error""") | ||||
def getblockchaininfo(self): | def getblockchaininfo(self): | ||||
self.checkFailCounter() | self.checkFailCounter() | ||||
return super().getblockchaininfo() | return super().getblockchaininfo() | ||||
def getblockhash(self, block): | def getblockhash(self, block): | ||||
self.checkFailCounter() | self.checkFailCounter() | ||||
return super().getblockhash(block) | return super().getblockhash(block) | ||||
def getblockheader(self, blockHash): | def getblockheader(self, blockHash): | ||||
self.checkFailCounter() | self.checkFailCounter() | ||||
return super().getblockheader(blockHash) | return super().getblockheader(blockHash) | ||||
def gettxoutsetinfo(self): | |||||
self.checkFailCounter() | |||||
return super().gettxoutsetinfo() | |||||
def CheckMockFailure(test, args, errorMessage='error code: -99'): | def CheckMockFailure(test, args, errorMessage='error code: -99'): | ||||
with test.assertRaises(Exception) as context: | with test.assertRaises(Exception) as context: | ||||
GenerateChainParams(args) | GenerateChainParams(args) | ||||
test.assertIn(errorMessage, str(context.exception)) | test.assertIn(errorMessage, str(context.exception)) | ||||
class GenerateChainParamsTests(unittest.TestCase): | class GenerateChainParamsTests(unittest.TestCase): | ||||
maxDiff = None | maxDiff = None | ||||
def setUp(self): | def setUp(self): | ||||
self.blockHash1 = '0000000000000000003ef673ae12bc6017481830d37b9c52ce1e79c080e812b8' | self.blockHash1 = '0000000000000000003ef673ae12bc6017481830d37b9c52ce1e79c080e812b8' | ||||
self.chainWork1 = '000000000000000000000000000000000000000000f2537ccf2e07bbe15e70e1' | self.chainWork1 = '000000000000000000000000000000000000000000f2537ccf2e07bbe15e70e1' | ||||
self.blockHash2 = '0000000000000298a9fa227f0ec32f2b7585f3e64c8b3369e7f8b4fd8ea3d836' | self.blockHash2 = '0000000000000298a9fa227f0ec32f2b7585f3e64c8b3369e7f8b4fd8ea3d836' | ||||
self.chainWork2 = '00000000000000000000000000000000000000000000004fdb4795a837f19671' | self.chainWork2 = '00000000000000000000000000000000000000000000004fdb4795a837f19671' | ||||
def test_happy_path_mainnet(self): | def test_happy_path_mainnet(self): | ||||
mockRPC = MockRPC(test=self, chain='main', numBlocks=123000, | mockRPC = MockRPC( | ||||
expectedBlock=122990, blockHash=self.blockHash1, chainWork=self.chainWork1) | test=self, | ||||
chain='main', | |||||
numBlocks=123000, | |||||
expectedBlock=122990, | |||||
blockHash=self.blockHash1, | |||||
chainWork=self.chainWork1, | |||||
blockchainSize=160111222333, | |||||
chainstateSize=2000111222) | |||||
args = { | args = { | ||||
'rpc': mockRPC, | 'rpc': mockRPC, | ||||
'block': None, | 'block': None, | ||||
} | } | ||||
self.assertEqual(GenerateChainParams(args), "{}\n{}".format( | self.assertEqual(GenerateChainParams(args), "\n".join([ | ||||
"0000000000000000003ef673ae12bc6017481830d37b9c52ce1e79c080e812b8", | "0000000000000000003ef673ae12bc6017481830d37b9c52ce1e79c080e812b8", | ||||
"000000000000000000000000000000000000000000f2537ccf2e07bbe15e70e1")) | "000000000000000000000000000000000000000000f2537ccf2e07bbe15e70e1", | ||||
"194", "3"])) | |||||
def test_happy_path_testnet(self): | def test_happy_path_testnet(self): | ||||
mockRPC = MockRPC(test=self, chain='test', numBlocks=234000, | mockRPC = MockRPC( | ||||
expectedBlock=232000, blockHash=self.blockHash1, chainWork=self.chainWork1) | test=self, | ||||
chain='test', | |||||
numBlocks=234000, | |||||
expectedBlock=232000, | |||||
blockHash=self.blockHash1, | |||||
chainWork=self.chainWork1, | |||||
blockchainSize=50111222333, | |||||
chainstateSize=1000111222) | |||||
args = { | args = { | ||||
'rpc': mockRPC, | 'rpc': mockRPC, | ||||
'block': None, | 'block': None, | ||||
} | } | ||||
self.assertEqual(GenerateChainParams(args), "{}\n{}".format( | self.assertEqual(GenerateChainParams(args), "\n".join([ | ||||
"0000000000000000003ef673ae12bc6017481830d37b9c52ce1e79c080e812b8", | "0000000000000000003ef673ae12bc6017481830d37b9c52ce1e79c080e812b8", | ||||
"000000000000000000000000000000000000000000f2537ccf2e07bbe15e70e1")) | "000000000000000000000000000000000000000000f2537ccf2e07bbe15e70e1", | ||||
"61", "2"])) | |||||
def test_specific_block(self): | def test_specific_block(self): | ||||
mockRPC = MockRPC(test=self, chain='main', numBlocks=123000, | mockRPC = MockRPC( | ||||
expectedBlock=122990, blockHash=self.blockHash1, chainWork=self.chainWork1) | test=self, | ||||
chain='main', | |||||
numBlocks=123000, | |||||
expectedBlock=122990, | |||||
blockHash=self.blockHash1, | |||||
chainWork=self.chainWork1, | |||||
blockchainSize=160111222333, | |||||
chainstateSize=2000111222) | |||||
args = { | args = { | ||||
'rpc': mockRPC, | 'rpc': mockRPC, | ||||
'block': self.blockHash1, | 'block': self.blockHash1, | ||||
} | } | ||||
self.assertEqual(GenerateChainParams(args), "{}\n{}".format( | self.assertEqual(GenerateChainParams(args), "\n".join([ | ||||
"0000000000000000003ef673ae12bc6017481830d37b9c52ce1e79c080e812b8", | "0000000000000000003ef673ae12bc6017481830d37b9c52ce1e79c080e812b8", | ||||
"000000000000000000000000000000000000000000f2537ccf2e07bbe15e70e1")) | "000000000000000000000000000000000000000000f2537ccf2e07bbe15e70e1", | ||||
"194", "3"])) | |||||
def test_wrong_chain(self): | def test_wrong_chain(self): | ||||
mockRPC = MockRPC(test=self, chain='main', numBlocks=123000, | mockRPC = MockRPC( | ||||
expectedBlock=122990, blockHash=self.blockHash1, chainWork=self.chainWork1) | test=self, | ||||
chain='main', | |||||
numBlocks=123000, | |||||
expectedBlock=122990, | |||||
blockHash=self.blockHash1, | |||||
chainWork=self.chainWork1, | |||||
blockchainSize=160111222333, | |||||
chainstateSize=2000111222) | |||||
args = { | args = { | ||||
'rpc': mockRPC, | 'rpc': mockRPC, | ||||
'block': self.blockHash2, | 'block': self.blockHash2, | ||||
} | } | ||||
CheckMockFailure( | CheckMockFailure( | ||||
self, args, "expected was 'getblockheader 0000000000000000003ef673ae12bc6017481830d37b9c52ce1e79c080e812b8'") | self, args, "expected was 'getblockheader 0000000000000000003ef673ae12bc6017481830d37b9c52ce1e79c080e812b8'") | ||||
def test_bitcoin_cli_failures_testnet(self): | def test_bitcoin_cli_failures_testnet(self): | ||||
for chain in ['main', 'test']: | for chain in ['main', 'test']: | ||||
expectedBlock = 133990 | expectedBlock = 133990 | ||||
if chain == 'test': | if chain == 'test': | ||||
expectedBlock = 132000 | expectedBlock = 132000 | ||||
for failCounter in range(3): | for failCounter in range(4): | ||||
mockFailRPC = MockFailRPC(test=self, chain=chain, numBlocks=134000, expectedBlock=expectedBlock, | mockFailRPC = MockFailRPC( | ||||
blockHash=self.blockHash1, chainWork=self.chainWork1, failCounter=failCounter) | test=self, | ||||
chain=chain, | |||||
numBlocks=134000, | |||||
expectedBlock=expectedBlock, | |||||
blockHash=self.blockHash1, | |||||
chainWork=self.chainWork1, | |||||
failCounter=failCounter, | |||||
blockchainSize=160111222333, | |||||
chainstateSize=2000111222) | |||||
argsFail = { | argsFail = { | ||||
'rpc': mockFailRPC, | 'rpc': mockFailRPC, | ||||
'block': None, | 'block': None, | ||||
} | } | ||||
CheckMockFailure(self, argsFail) | CheckMockFailure(self, argsFail) | ||||
unittest.main() | unittest.main() |