ts_regtest.py 8.0 KB

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