ts_regtest.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. #!/usr/bin/env python3
  2. #
  3. # mmgen = Multi-Mode GENerator, a command-line cryptocurrency wallet
  4. # Copyright (C)2013-2022 The MMGen Project <mmgen@tuta.io>
  5. # Licensed under the GNU General Public License, Version 3:
  6. # https://www.gnu.org/licenses
  7. # Public project repositories:
  8. # https://github.com/mmgen/mmgen-node-tools
  9. # https://gitlab.com/mmgen/mmgen-node-tools
  10. """
  11. ts_regtest.py: Regtest tests for the test.py test suite
  12. """
  13. import os
  14. from mmgen.globalvars import g
  15. from mmgen.opts import opt
  16. from mmgen.util import die,gmsg
  17. from mmgen.protocol import init_proto
  18. from ..include.common import *
  19. from .common import *
  20. from .ts_base import *
  21. args1 = ['--bob']
  22. args2 = ['--bob','--rpc-backend=http']
  23. def gen_addrs(proto,network,keys):
  24. from mmgen.tool.api import tool_api
  25. tool = tool_api()
  26. tool.init_coin(proto.coin,'regtest')
  27. tool.addrtype = proto.mmtypes[-1]
  28. return [tool.privhex2addr('{:064x}'.format(key)) for key in keys]
  29. class TestSuiteRegtest(TestSuiteBase):
  30. 'various operations via regtest mode'
  31. networks = ('btc','ltc','bch')
  32. passthru_opts = ('coin',)
  33. extra_spawn_args = ['--regtest=1']
  34. tmpdir_nums = [1]
  35. color = True
  36. deterministic = False
  37. cmd_group_in = (
  38. ('setup', 'regtest mode setup'),
  39. ('subgroup.halving_calculator', []),
  40. ('subgroup.fund_addrbal', []),
  41. ('subgroup.addrbal', ['fund_addrbal']),
  42. ('subgroup.blocks_info', ['addrbal']),
  43. ('stop', 'stopping regtest daemon'),
  44. )
  45. cmd_subgroups = {
  46. 'halving_calculator': (
  47. "'mmnode-halving-calculator' script",
  48. ('halving_calculator1', "halving calculator (--help)"),
  49. ('halving_calculator2', "halving calculator"),
  50. ('halving_calculator3', "halving calculator (--list)"),
  51. ('halving_calculator4', "halving calculator (--mined)"),
  52. ('halving_calculator5', "halving calculator (--mined --bdr-proj=5)"),
  53. ('halving_calculator6', "halving calculator (--mined --sample-size=20)"),
  54. ),
  55. 'fund_addrbal': (
  56. "funding addresses for 'addrbal' subgroup",
  57. ('sendto1', 'sending funds to address #1 (1)'),
  58. ('sendto2', 'sending funds to address #1 (2)'),
  59. ('sendto3', 'sending funds to address #2'),
  60. ),
  61. 'addrbal': (
  62. "'mmnode-addrbal' script",
  63. ('addrbal_single', 'getting address balance (single address)'),
  64. ('addrbal_multiple', 'getting address balances (multiple addresses)'),
  65. ('addrbal_multiple_tabular1', 'getting address balances (multiple addresses, tabular output)'),
  66. ('addrbal_multiple_tabular2', 'getting address balances (multiple addresses, tabular, show first block)'),
  67. ('addrbal_nobal1', 'getting address balances (no balance)'),
  68. ('addrbal_nobal2', 'getting address balances (no balances)'),
  69. ('addrbal_nobal3', 'getting address balances (one null balance)'),
  70. ('addrbal_nobal3_tabular1', 'getting address balances (one null balance, tabular output)'),
  71. ('addrbal_nobal3_tabular2', 'getting address balances (one null balance, tabular, show first block)'),
  72. ),
  73. 'blocks_info': (
  74. "'mmnode-blocks-info' script",
  75. ('blocks_info1', "blocks-info (--help)"),
  76. ('blocks_info2', "blocks-info (no args)"),
  77. ('blocks_info3', "blocks-info +100"),
  78. ('blocks_info4', "blocks-info --miner-info --fields=all --stats=all +1"),
  79. ),
  80. }
  81. def __init__(self,trunner,cfgs,spawn):
  82. TestSuiteBase.__init__(self,trunner,cfgs,spawn)
  83. if trunner == None:
  84. return
  85. if self.proto.testnet:
  86. die(2,'--testnet and --regtest options incompatible with regtest test suite')
  87. self.proto = init_proto(self.proto.coin,network='regtest',need_amt=True)
  88. self.addrs = gen_addrs(self.proto,'regtest',[1,2,3,4,5])
  89. def setup(self):
  90. stop_test_daemons(self.proto.network_id,force=True,remove_datadir=True)
  91. from shutil import rmtree
  92. try: rmtree(joinpath(self.tr.data_dir,'regtest'))
  93. except: pass
  94. t = self.spawn('mmgen-regtest',['-n','setup'])
  95. for s in ('Starting','Creating','Creating','Creating','Mined','Setup complete'):
  96. t.expect(s)
  97. return t
  98. def halving_calculator(self,add_args,expect_list):
  99. t = self.spawn('mmnode-halving-calculator',args1+add_args)
  100. t.match_expect_list(expect_list)
  101. return t
  102. def halving_calculator1(self):
  103. return self.halving_calculator(['--help'],['USAGE:'])
  104. def halving_calculator2(self):
  105. return self.halving_calculator([],['Current block: 393',f'Current block subsidy: 12.5 {g.coin}'])
  106. def halving_calculator3(self):
  107. return self.halving_calculator(['--list'],['33 4950','0'])
  108. def halving_calculator4(self):
  109. return self.halving_calculator(['--mined'],['0 0.0000015 14949.9999835'])
  110. def halving_calculator5(self):
  111. return self.halving_calculator(['--mined','--bdr-proj=5'],['5.00000 0 0.0000015 14949.9999835'])
  112. def halving_calculator6(self):
  113. return self.halving_calculator(['--mined','--sample-size=20'],['33 4950','0 0.0000015 14949.9999835'])
  114. def sendto(self,addr,amt):
  115. return self.spawn('mmgen-regtest',['send',addr,amt])
  116. def sendto1(self): return self.sendto(self.addrs[0],'0.123')
  117. def sendto2(self): return self.sendto(self.addrs[0],'0.234')
  118. def sendto3(self): return self.sendto(self.addrs[1],'0.345')
  119. def addrbal(self,args,expect_list):
  120. t = self.spawn('mmnode-addrbal',args)
  121. t.match_expect_list(expect_list)
  122. return t
  123. def addrbal_single(self):
  124. return self.addrbal(
  125. args2 + [self.addrs[0]],
  126. [
  127. f'Balance: 0.357 {g.coin}',
  128. '2 unspent outputs in 2 blocks',
  129. '394','0.123',
  130. '395','0.234'
  131. ])
  132. def addrbal_multiple(self):
  133. return self.addrbal(
  134. args2 + [self.addrs[1],self.addrs[0]],
  135. [
  136. '396','0.345',
  137. '394','0.123',
  138. '395','0.234'
  139. ])
  140. def addrbal_multiple_tabular1(self):
  141. return self.addrbal(
  142. args2 + ['--tabular',self.addrs[1],self.addrs[0]],
  143. [
  144. self.addrs[1] + ' 1 396','0.345',
  145. self.addrs[0] + ' 2 395','0.357'
  146. ])
  147. def addrbal_multiple_tabular2(self):
  148. return self.addrbal(
  149. args2 + ['--tabular','--first-block',self.addrs[1],self.addrs[0]],
  150. [
  151. self.addrs[1] + ' 1 396','396','0.345',
  152. self.addrs[0] + ' 2 394','395','0.357'
  153. ])
  154. def addrbal_nobal1(self):
  155. return self.addrbal(
  156. args2 + [self.addrs[2]], ['Address has no balance'] )
  157. def addrbal_nobal2(self):
  158. return self.addrbal(
  159. args2 + [self.addrs[2],self.addrs[3]], ['Addresses have no balances'] )
  160. def addrbal_nobal3(self):
  161. return self.addrbal(
  162. args2 + [self.addrs[4],self.addrs[0],self.addrs[3]],
  163. [
  164. 'No balance',
  165. '2 unspent outputs in 2 blocks',
  166. '394','0.123','395','0.234',
  167. 'No balance'
  168. ])
  169. def addrbal_nobal3_tabular1(self):
  170. return self.addrbal(
  171. args2 + ['--tabular',self.addrs[4],self.addrs[0],self.addrs[3]],
  172. [
  173. self.addrs[4] + ' - - -',
  174. self.addrs[0] + ' 2 395','0.357',
  175. self.addrs[3] + ' - - -',
  176. ])
  177. def addrbal_nobal3_tabular2(self):
  178. return self.addrbal(
  179. args2 + ['--tabular','--first-block',self.addrs[4],self.addrs[0],self.addrs[3]],
  180. [
  181. self.addrs[4] + ' - - - -',
  182. self.addrs[0] + ' 2 394','395','0.357',
  183. self.addrs[3] + ' - - - -',
  184. ])
  185. def blocks_info(self,args,expect_list):
  186. t = self.spawn('mmnode-blocks-info',args)
  187. t.match_expect_list(expect_list)
  188. return t
  189. def blocks_info1(self):
  190. return self.blocks_info( args1 + ['--help'], ['USAGE:','OPTIONS:'])
  191. def blocks_info2(self):
  192. return self.blocks_info( args1, [
  193. 'Current height: 396',
  194. ])
  195. def blocks_info3(self):
  196. return self.blocks_info( args1 + ['+100'], [
  197. 'Range: 297-396',
  198. 'Current height: 396',
  199. 'Next diff adjust: 2016'
  200. ])
  201. def blocks_info4(self):
  202. n1,i1,o1,n2,i2,o2 = (2,1,3,6,3,9) if g.coin == 'BCH' else (2,1,4,6,3,12)
  203. return self.blocks_info( args1 + ['--miner-info','--fields=all','--stats=all','+3'], [
  204. 'Averages',
  205. f'nTx: {n1}',
  206. f'Inputs: {i1}',
  207. f'Outputs: {o1}',
  208. 'Totals',
  209. f'nTx: {n2}',
  210. f'Inputs: {i2}',
  211. f'Outputs: {o2}',
  212. 'Current height: 396',
  213. 'Next diff adjust: 2016'
  214. ])
  215. def stop(self):
  216. if opt.no_daemon_stop:
  217. self.spawn('',msg_only=True)
  218. msg_r('(leaving daemon running by user request)')
  219. return 'ok'
  220. else:
  221. return self.spawn('mmgen-regtest',['stop'])