def __init__(self, dataDir, isTestNet): QtCore.QObject.__init__(self) self.lock = threading.Lock() self._patching_BaseTxDb() self.wallet_path = os.path.join(dataDir, 'wallet.sqlite') self._pwallet = PersistentWallet(self.wallet_path, isTestNet) self._set_wallet_settings(dataDir, isTestNet) self._pwallet.init_model() self._wallet = self._pwallet.get_model() self._controller = WalletController(self._wallet) self._utxo_fetcher = AsyncUTXOFetcher( self._wallet, self._pwallet.wallet_config.get('utxo_fetcher', {})) self._utxo_fetcher_timer = QtCore.QTimer() self._utxo_fetcher_timer.timeout.connect(self._utxo_fetcher.update) self._utxo_fetcher_timer.setInterval(1000) asset = self.get_asset_definition('bitcoin') if len(self._controller.get_all_addresses(asset)) == 0: self._controller.get_new_address(asset) self._create_club_asset()
class TestRealP2PTrade(unittest.TestCase): def setUp(self): from ngcccbase.pwallet import PersistentWallet from ngcccbase.wallet_controller import WalletController self.pwallet = PersistentWallet(":memory:", True) self.pwallet.init_model() self.wctrl = WalletController(self.pwallet.wallet_model) def test_real(self): ewctrl = EWalletController(self.pwallet.get_model(), self.wctrl) config = {"offer_expiry_interval": 30, "ep_expiry_interval": 30} comm1 = MockComm() comm2 = MockComm() comm1.add_peer(comm2) comm2.add_peer(comm1) agent1 = EAgent(ewctrl, config, comm1) agent2 = EAgent(ewctrl, config, comm2) self.cd0 = "obc:cc8e64cef1a880f5132e73b5a1f52a72565c92afa8ec36c445c635fe37b372fd:0:263370" self.cd1 = "obc:caff27b3fe0a826b776906aceafecac7bb34af16971b8bd790170329309391ac:0:265577" cv0 = {'color_spec': self.cd0, 'value': 100} cv1 = {'color_spec': self.cd1, 'value': 200} ag1_offer = MyEOffer(None, cv0, cv1) ag2_offer = MyEOffer(None, cv0, cv1) ag2_offer.auto_post = False agent1.register_my_offer(ag1_offer) agent2.register_my_offer(ag2_offer) for _ in xrange(3): agent1._update_state() agent2._update_state()
class TestRealP2PTrade(unittest.TestCase): def setUp(self): from ngcccbase.pwallet import PersistentWallet from ngcccbase.wallet_controller import WalletController self.pwallet = PersistentWallet(":memory:", True) self.pwallet.init_model() self.wctrl = WalletController(self.pwallet.wallet_model) def test_real(self): ewctrl = EWalletController(self.pwallet.get_model(), self.wctrl) config = {"offer_expiry_interval": 30, "ep_expiry_interval": 30} comm1 = MockComm() comm2 = MockComm() comm1.add_peer(comm2) comm2.add_peer(comm1) agent1 = EAgent(ewctrl, config, comm1) agent2 = EAgent(ewctrl, config, comm2) self.cd0 = "obc:cc8e64cef1a880f5132e73b5a1f52a72565c92afa8ec36c445c635fe37b372fd:0:263370" self.cd1 = "obc:caff27b3fe0a826b776906aceafecac7bb34af16971b8bd790170329309391ac:0:265577" cv0 = { 'color_spec' : self.cd0, 'value' : 100 } cv1 = { 'color_spec' : self.cd1, 'value' : 200 } ag1_offer = MyEOffer(None, cv0, cv1) ag2_offer = MyEOffer(None, cv0, cv1) ag2_offer.auto_post = False agent1.register_my_offer(ag1_offer) agent2.register_my_offer(ag2_offer) for _ in xrange(3): agent1._update_state() agent2._update_state()
def __init__(self, wallet=None, testnet=False): # sanitize inputs testnet = sanitize.flag(testnet) if not wallet: wallet = "%s.wallet" % ("testnet" if testnet else "mainnet") self.wallet = PersistentWallet(wallet, testnet) self.model_is_initialized = False
def __init__(self): parser = argparse.ArgumentParser() parser.add_argument("--wallet", dest="wallet_path") parsed_args = vars(parser.parse_args()) self.wallet = PersistentWallet(parsed_args.get('wallet_path')) self.wallet.init_model() self.model = self.wallet.get_model() self.controller = WalletController(self.wallet.get_model())
def __init__(self, wallet=None, testnet=False): # sanitize inputs testnet = sanitize.flag(testnet) if not wallet: wallet = "%s.wallet" % ("testnet" if testnet else "mainnet") self.wallet = PersistentWallet(wallet, testnet) self.wallet.init_model() self.model = self.wallet.get_model() self.controller = WalletController(self.model)
def setUp(self): self.path = ":memory:" self.config = { 'dw_master_key': 'test', 'testnet': True, 'ccc': { 'colordb_path': self.path }, 'bip0032': False } self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() self.wc = WalletController(self.model) self.wc.testing = True self.wc.debug = True self.colormap = self.model.get_color_map() self.bcolorset = ColorSet(self.colormap, ['']) wam = self.model.get_address_manager() self.baddress = wam.get_new_address(self.bcolorset) self.baddr = self.baddress.get_address() self.blockhash = '00000000c927c5d0ee1ca362f912f83c462f644e695337ce3731b9f7c5d1ca8c' self.txhash = '4fe45a5ba31bab1e244114c4555d9070044c73c98636231c77657022d76b87f7' script = tools.compile( "OP_DUP OP_HASH160 {0} OP_EQUALVERIFY OP_CHECKSIG".format( self.baddress.rawPubkey().encode("hex"))).encode("hex") self.model.utxo_man.store.add_utxo(self.baddr, self.txhash, 0, 100, script) script = tools.compile( "OP_DUP OP_HASH160 {0} OP_EQUALVERIFY OP_CHECKSIG".format( self.baddress.rawPubkey().encode("hex"))).encode("hex") self.model.utxo_man.store.add_utxo(self.baddr, self.txhash, 1, 1000000000, script) self.model.ccc.blockchain_state.bitcoind = MockBitcoinD('test') def x(s): return self.blockhash, True self.model.ccc.blockchain_state.get_tx_blockhash = x self.moniker = 'test' self.wc.issue_coins(self.moniker, 'obc', 10000, 1) self.asset = self.model.get_asset_definition_manager( ).get_asset_by_moniker(self.moniker) self.basset = self.model.get_asset_definition_manager( ).get_asset_by_moniker('bitcoin') self.color_id = list(self.asset.color_set.color_id_set)[0] self.model.ccc.metastore.set_as_scanned(self.color_id, self.blockhash)
def __init__(self): parser = argparse.ArgumentParser() parser.add_argument("--wallet", dest="wallet_path") parser.add_argument("--testnet", action='store_true') parsed_args = vars(parser.parse_args()) self.wallet = PersistentWallet(parsed_args.get('wallet_path'), parsed_args.get('testnet')) self.wallet.init_model() self.model = self.wallet.get_model() self.controller = WalletController(self.wallet.get_model()) self.async_utxo_fetcher = AsyncUTXOFetcher( self.model, self.wallet.wallet_config.get('utxo_fetcher', {}))
def add_coins(self): self.config['asset_definitions'] = [ { "color_set": [""], "monikers": ["bitcoin"], "unit": 100000000 }, { "color_set": [self.cspec], "monikers": ['test'], "unit": 1 }, ] self.config['hdwam'] = { "genesis_color_sets": [ [self.cspec], ], "color_set_states": [ { "color_set": [""], "max_index": 1 }, { "color_set": [self.cspec], "max_index": 7 }, ] } self.config['bip0032'] = True self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() self.ewc.model = self.model self.wc.model = self.model # modify model colored coin context, so test runs faster ccc = self.model.ccc cdbuilder = ColorDataBuilderManager(ccc.colormap, ccc.blockchain_state, ccc.cdstore, ccc.metastore, AidedColorDataBuilder) ccc.colordata = ThinColorData(cdbuilder, ccc.blockchain_state, ccc.cdstore, ccc.colormap) # need to query the blockchain self.model.utxo_man.update_all() adm = self.model.get_asset_definition_manager() asset = adm.get_asset_by_moniker('test') cq = self.model.make_coin_query({"asset": asset}) utxo_list = cq.get_result()
class TestRealP2PTrade(unittest.TestCase): def setUp(self): from ngcccbase.pwallet import PersistentWallet from ngcccbase.wallet_controller import WalletController self.pwallet = PersistentWallet() self.pwallet.init_model() self.wctrl = WalletController(self.pwallet.wallet_model) def test_real(self): ewctrl = EWalletController(self.pwallet.get_model(), self.wctrl) config = {"offer_expiry_interval": 30, "ep_expiry_interval": 30} comm1 = MockComm() comm2 = MockComm() comm1.add_peer(comm2) comm2.add_peer(comm1) agent1 = EAgent(ewctrl, config, comm1) agent2 = EAgent(ewctrl, config, comm2) frobla_color_desc = "obc:cc8e64cef1a880f5132e73b5a1f52a72565c92afa8ec36c445c635fe37b372fd:0:263370" foo_color_desc = "obc:caff27b3fe0a826b776906aceafecac7bb34af16971b8bd790170329309391ac:0:265577" self.cd0 = OBColorDefinition( 1, { 'txhash': 'cc8e64cef1a880f5132e73b5a1f52a72565c92afa8ec36c445c635fe37b372fd', 'outindex': 0, 'height': 263370 }) self.cd1 = OBColorDefinition( 1, { 'txhash': 'caff27b3fe0a826b776906aceafecac7bb34af16971b8bd790170329309391ac', 'outindex': 0, 'height': 265577 }) cv0 = SimpleColorValue(colordef=self.cd0, value=100) cv1 = SimpleColorValue(colordef=self.cd1, value=200) ag1_offer = MyEOffer(None, cv0, cv1) ag2_offer = MyEOffer(None, cv0, cv1, False) agent1.register_my_offer(ag1_offer) agent2.register_my_offer(ag2_offer) for _ in xrange(3): agent1._update_state() agent2._update_state()
def add_coins(self): self.config['asset_definitions'] = [ {"color_set": [""], "monikers": ["bitcoin"], "unit": 100000000}, {"color_set": [self.cspec], "monikers": ['test'], "unit": 1},] self.config['hdwam'] = { "genesis_color_sets": [ [self.cspec], ], "color_set_states": [ {"color_set": [""], "max_index": 1}, {"color_set": [self.cspec], "max_index": 7}, ] } self.config['bip0032'] = True self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() self.ewc.model = self.model self.wc.model = self.model # modify model colored coin context, so test runs faster ccc = self.model.ccc cdbuilder = ColorDataBuilderManager( ccc.colormap, ccc.blockchain_state, ccc.cdstore, ccc.metastore, AidedColorDataBuilder) ccc.colordata = ThinColorData( cdbuilder, ccc.blockchain_state, ccc.cdstore, ccc.colormap) # need to query the blockchain self.model.utxo_man.update_all() adm = self.model.get_asset_definition_manager() asset = adm.get_asset_by_moniker('test') cq = self.model.make_coin_query({"asset": asset}) utxo_list = cq.get_result()
def setUp(self): self.path = ":memory:" self.config = { 'hdw_master_key': '91813223e97697c42f05e54b3a85bae601f04526c5c053ff0811747db77cfdf5f1accb50b3765377c379379cd5aa512c38bf24a57e4173ef592305d16314a0f4', 'testnet': True, 'ccc': {'colordb_path' : self.path}, } self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() self.colormap = self.model.get_color_map() self.bcolorset = ColorSet(self.colormap, ['']) self.basset = self.model.get_asset_definition_manager( ).get_asset_by_moniker('bitcoin') self.cqf = self.model.get_coin_query_factory()
def setUp(self): self.pwallet = PersistentWallet(None, True) self.pwallet.init_model() self.model = self.pwallet.get_model() adm = self.model.get_asset_definition_manager() # make sure you have the asset 'testobc' in your testnet.wallet !! self.asset = adm.get_asset_by_moniker('testobc') self.color_spec = self.asset.get_color_set().get_data()[0] self.wc = WalletController(self.model) self.ewc = EWalletController(self.model, self.wc) def null(a): pass self.wc.publish_tx = null
def setUpClass(cls): import signal signal.signal(signal.SIGINT, signal.SIG_DFL) #cls.tempdir = tempfile.mkdtemp() cls.tempdir = '/path/to/folder' cls.pwallet = PersistentWallet( os.path.join(cls.tempdir, 'testnet.wallet'), True) cls.pwallet.init_model() cls.vbs = VerifierBlockchainState(cls.tempdir, ChromaBlockchainState())
def setUp(self): self.path = ":memory:" self.config = { 'hdw_master_key': '91813223e97697c42f05e54b3a85bae601f04526c5c053ff0811747db77cfdf5f1accb50b3765377c379379cd5aa512c38bf24a57e4173ef592305d16314a0f4', 'testnet': True, 'ccc': { 'colordb_path': self.path }, } self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() self.wc = WalletController(self.model) self.ewc = EWalletController(self.model, self.wc) self.bcolorset = self.ewc.resolve_color_spec('') self.cspec = "obc:03524a4d6492e8d43cb6f3906a99be5a1bcd93916241f759812828b301f25a6c:0:153267"
def __getattribute__(self, name): if name in ['controller', 'model', 'wallet']: try: data = self.data except AttributeError: self.data = data = {} pw = PersistentWallet(self.args.get('wallet_path')) pw.init_model() wallet_model = pw.get_model() data.update({ 'controller': WalletController(wallet_model) if wallet_model else None, 'wallet': pw, 'model': wallet_model if pw else None, }) return data[name] return object.__getattribute__(self, name)
def test_get_history(self): self.config['asset_definitions'] = [ {"color_set": [""], "monikers": ["bitcoin"], "unit": 100000000}, {"color_set": ["obc:03524a4d6492e8d43cb6f3906a99be5a1bcd93916241f759812828b301f25a6c:0:153267"], "monikers": ['test'], "unit": 1},] self.config['hdwam'] = { "genesis_color_sets": [ ["obc:03524a4d6492e8d43cb6f3906a99be5a1bcd93916241f759812828b301f25a6c:0:153267"], ], "color_set_states": [ {"color_set": [""], "max_index": 1}, {"color_set": ["obc:03524a4d6492e8d43cb6f3906a99be5a1bcd93916241f759812828b301f25a6c:0:153267"], "max_index": 7}, ] } self.config['bip0032'] = True self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() # modify model colored coin context, so test runs faster ccc = self.model.ccc cdbuilder = ColorDataBuilderManager( ccc.colormap, ccc.blockchain_state, ccc.cdstore, ccc.metastore, AidedColorDataBuilder) ccc.colordata = ThinColorData( cdbuilder, ccc.blockchain_state, ccc.cdstore, ccc.colormap) wc = WalletController(self.model) adm = self.model.get_asset_definition_manager() asset = adm.get_asset_by_moniker('test') self.model.utxo_man.update_all() cq = self.model.make_coin_query({"asset": asset}) utxo_list = cq.get_result() # send to the second address so the mempool has something addrs = wc.get_all_addresses(asset) wc.send_coins(asset, [addrs[1].get_color_address()], [1000]) history = self.model.get_history_for_asset(asset) self.assertTrue(len(history) > 30)
class TestRealP2PTrade(unittest.TestCase): def setUp(self): from ngcccbase.pwallet import PersistentWallet from ngcccbase.wallet_controller import WalletController self.pwallet = PersistentWallet() self.pwallet.init_model() self.wctrl = WalletController(self.pwallet.wallet_model) def test_real(self): ewctrl = EWalletController(self.pwallet.get_model(), self.wctrl) config = {"offer_expiry_interval": 30, "ep_expiry_interval": 30} comm1 = MockComm() comm2 = MockComm() comm1.add_peer(comm2) comm2.add_peer(comm1) agent1 = EAgent(ewctrl, config, comm1) agent2 = EAgent(ewctrl, config, comm2) frobla_color_desc = "obc:cc8e64cef1a880f5132e73b5a1f52a72565c92afa8ec36c445c635fe37b372fd:0:263370" foo_color_desc = "obc:caff27b3fe0a826b776906aceafecac7bb34af16971b8bd790170329309391ac:0:265577" self.cd0 = OBColorDefinition(1, {'txhash': 'cc8e64cef1a880f5132e73b5a1f52a72565c92afa8ec36c445c635fe37b372fd', 'outindex': 0, 'height':263370}) self.cd1 = OBColorDefinition(1, {'txhash': 'caff27b3fe0a826b776906aceafecac7bb34af16971b8bd790170329309391ac', 'outindex': 0, 'height':265577}) cv0 = SimpleColorValue(colordef=self.cd0, value=100) cv1 = SimpleColorValue(colordef=self.cd1, value=200) ag1_offer = MyEOffer(None, cv0, cv1) ag2_offer = MyEOffer(None, cv0, cv1, False) agent1.register_my_offer(ag1_offer) agent2.register_my_offer(ag2_offer) for _ in xrange(3): agent1._update_state() agent2._update_state()
def setUp(self): self.path = ":memory:" self.config = { 'hdw_master_key': '91813223e97697c42f05e54b3a85bae601f04526c5c053ff0811747db77cfdf5f1accb50b3765377c379379cd5aa512c38bf24a57e4173ef592305d16314a0f4', 'testnet': True, 'ccc': { 'colordb_path': self.path }, } self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() self.wc = WalletController(self.model) self.ewc = EWalletController(self.model, self.wc) self.econfig = {"offer_expiry_interval": 30, "ep_expiry_interval": 30} self.comm0 = MockComm() self.comm1 = MockComm() self.comm0.add_peer(self.comm1) self.comm1.add_peer(self.comm0) self.agent0 = EAgent(self.ewc, self.econfig, self.comm0) self.agent1 = EAgent(self.ewc, self.econfig, self.comm1) self.cspec = "obc:03524a4d6492e8d43cb6f3906a99be5a1bcd93916241f759812828b301f25a6c:0:153267"
def setUp(self): self.pwallet = PersistentWallet(None, True) self.pwallet.init_model() self.model = self.pwallet.get_model() adm = self.model.get_asset_definition_manager() # make sure you have the asset 'testobc' in your testnet.wallet !! self.asset = adm.get_asset_by_moniker('testobc') self.color_spec = self.asset.get_color_set().get_data()[0] self.comm0 = MockComm() self.comm1 = MockComm() self.comm0.add_peer(self.comm1) self.comm1.add_peer(self.comm0) self.wc = WalletController(self.model) self.ewc = EWalletController(self.model, self.wc) self.econfig = {"offer_expiry_interval": 30, "ep_expiry_interval": 30} self.agent0 = EAgent(self.ewc, self.econfig, self.comm0) self.agent1 = EAgent(self.ewc, self.econfig, self.comm1) self.cv0 = {'color_spec': "", 'value': 100} self.cv1 = {'color_spec': self.color_spec, 'value': 200} self.offer0 = MyEOffer(None, self.cv0, self.cv1) self.offer1 = MyEOffer(None, self.cv1, self.cv0)
def __getattribute__(self, name): if name in ['controller', 'model', 'wallet']: if name in self.data: return self.data[name] if name == 'wallet': wallet = PersistentWallet(self.args.get('wallet_path'), self.args.get('testnet')) self.data['wallet'] = wallet return wallet else: self.wallet.init_model() self.data['model'] = self.data['wallet'].get_model() self.data['controller'] = WalletController(self.data['model']) return self.data[name] return object.__getattribute__(self, name)
def setUp(self): self.path = ":memory:" self.config = { 'hdw_master_key': '91813223e97697c42f05e54b3a85bae601f04526c5c053ff0811747db77cfdf5f1accb50b3765377c379379cd5aa512c38bf24a57e4173ef592305d16314a0f4', 'testnet': True, 'ccc': {'colordb_path' : self.path}, } self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() self.wc = WalletController(self.model) self.ewc = EWalletController(self.model, self.wc) self.bcolorset =self.ewc.resolve_color_spec('') self.cspec = "obc:03524a4d6492e8d43cb6f3906a99be5a1bcd93916241f759812828b301f25a6c:0:153267"
def add_coins(self): self.config['asset_definitions'] = [ {"color_set": [""], "monikers": ["bitcoin"], "unit": 100000000}, {"color_set": [self.cspec], "monikers": ['test'], "unit": 1},] self.config['hdwam'] = { "genesis_color_sets": [ [self.cspec], ], "color_set_states": [ {"color_set": [""], "max_index": 1}, {"color_set": [self.cspec], "max_index": 7}, ] } self.config['bip0032'] = True self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() self.ewc.model = self.model self.wc.model = self.model def null(a): pass self.wc.publish_tx = null # modify model colored coin context, so test runs faster ccc = self.model.ccc cdbuilder = ColorDataBuilderManager( ccc.colormap, ccc.blockchain_state, ccc.cdstore, ccc.metastore, AidedColorDataBuilder) ccc.colordata = ThinColorData( cdbuilder, ccc.blockchain_state, ccc.cdstore, ccc.colormap) # need to query the blockchain self.model.utxo_man.update_all() adm = self.model.get_asset_definition_manager() asset = adm.get_asset_by_moniker('test') cq = self.model.make_coin_query({"asset": asset}) utxo_list = cq.get_result() self.cd = ColorDefinition.from_color_desc(1, self.cspec) self.cv0 = SimpleColorValue(colordef=UNCOLORED_MARKER, value=100) self.cv1 = SimpleColorValue(colordef=self.cd, value=200) self.offer0 = MyEOffer(None, self.cv0, self.cv1) self.offer1 = MyEOffer(None, self.cv1, self.cv0)
def setUp(self): self.path = ":memory:" self.config = {'dw_master_key': 'test', 'testnet': True, 'ccc': { 'colordb_path' : self.path }, 'bip0032': False } self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() self.wc = WalletController(self.model) self.wc.testing = True self.wc.debug = True self.colormap = self.model.get_color_map() self.bcolorset = ColorSet(self.colormap, ['']) wam = self.model.get_address_manager() self.baddress = wam.get_new_address(self.bcolorset) self.baddr = self.baddress.get_address() self.blockhash = '00000000c927c5d0ee1ca362f912f83c462f644e695337ce3731b9f7c5d1ca8c' self.txhash = '4fe45a5ba31bab1e244114c4555d9070044c73c98636231c77657022d76b87f7' script = tools.compile( "OP_DUP OP_HASH160 {0} OP_EQUALVERIFY OP_CHECKSIG".format( self.baddress.rawPubkey().encode("hex"))).encode("hex") self.model.utxo_man.store.add_utxo(self.baddr, self.txhash, 0, 100, script) script = tools.compile( "OP_DUP OP_HASH160 {0} OP_EQUALVERIFY OP_CHECKSIG".format( self.baddress.rawPubkey().encode("hex"))).encode("hex") self.model.utxo_man.store.add_utxo(self.baddr, self.txhash, 1, 1000000000, script) self.model.ccc.blockchain_state.bitcoind = MockBitcoinD('test') def x(s): return self.blockhash, True self.model.ccc.blockchain_state.get_tx_blockhash = x self.moniker = 'test' self.wc.issue_coins(self.moniker, 'obc', 10000, 1) self.asset = self.model.get_asset_definition_manager( ).get_asset_by_moniker(self.moniker) self.basset = self.model.get_asset_definition_manager( ).get_asset_by_moniker('bitcoin') self.color_id = list(self.asset.color_set.color_id_set)[0] self.model.ccc.metastore.set_as_scanned(self.color_id, self.blockhash)
def setUp(self): self.path = ":memory:" self.config = { "hdw_master_key": "91813223e97697c42f05e54b3a85bae601f04526c5c053ff0811747db77cfdf5f1accb50b3765377c379379cd5aa512c38bf24a57e4173ef592305d16314a0f4", "testnet": True, "ccc": {"colordb_path": self.path}, } self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() self.wc = WalletController(self.model) self.ewc = EWalletController(self.model, self.wc) self.econfig = {"offer_expiry_interval": 30, "ep_expiry_interval": 30} self.comm0 = MockComm() self.comm1 = MockComm() self.comm0.add_peer(self.comm1) self.comm1.add_peer(self.comm0) self.agent0 = EAgent(self.ewc, self.econfig, self.comm0) self.agent1 = EAgent(self.ewc, self.econfig, self.comm1) self.cspec = "obc:03524a4d6492e8d43cb6f3906a99be5a1bcd93916241f759812828b301f25a6c:0:153267"
def setUp(self): self.pwallet = PersistentWallet(None, True) self.pwallet.init_model() self.model = self.pwallet.get_model() adm = self.model.get_asset_definition_manager() # make sure you have the asset 'testobc' in your testnet.wallet !! self.asset = adm.get_asset_by_moniker('testobc') self.color_spec = self.asset.get_color_set().get_data()[0] self.comm0 = MockComm() self.comm1 = MockComm() self.comm0.add_peer(self.comm1) self.comm1.add_peer(self.comm0) self.wc = WalletController(self.model) self.ewc = EWalletController(self.model, self.wc) self.econfig = {"offer_expiry_interval": 30, "ep_expiry_interval": 30} self.agent0 = EAgent(self.ewc, self.econfig, self.comm0) self.agent1 = EAgent(self.ewc, self.econfig, self.comm1) self.cv0 = { 'color_spec' : "", 'value' : 100 } self.cv1 = { 'color_spec' : self.color_spec, 'value' : 200 } self.offer0 = MyEOffer(None, self.cv0, self.cv1) self.offer1 = MyEOffer(None, self.cv1, self.cv0)
def setUp(self): from ngcccbase.pwallet import PersistentWallet from ngcccbase.wallet_controller import WalletController self.pwallet = PersistentWallet() self.pwallet.init_model() self.wctrl = WalletController(self.pwallet.wallet_model)
def command_import_config(self, **kwargs): """Special command for importing a JSON config. """ pw = PersistentWallet(kwargs.get('wallet_path'), kwargs['path'])
class TestTxcons(unittest.TestCase): def setUp(self): self.path = ":memory:" self.pwallet = PersistentWallet(self.path) self.config = { 'dw_master_key': 'test', 'testnet': True, 'ccc': { 'colordb_path': self.path }, 'bip0032': False } self.pwallet.wallet_config = self.config self.pwallet.init_model() self.model = self.pwallet.get_model() self.colormap = self.model.get_color_map() self.colordesc0 = "obc:color0:0:0" self.colordesc1 = "obc:color1:0:0" self.colordesc2 = "obc:color2:0:0" # add some colordescs self.colorid0 = self.colormap.resolve_color_desc(self.colordesc0) self.colorid1 = self.colormap.resolve_color_desc(self.colordesc1) self.colorid2 = self.colormap.resolve_color_desc(self.colordesc2) self.colordef0 = OBColorDefinition(self.colorid0, { 'txhash': 'color0', 'outindex': 0 }) self.colordef1 = OBColorDefinition(self.colorid1, { 'txhash': 'color1', 'outindex': 0 }) self.colordef2 = OBColorDefinition(self.colorid2, { 'txhash': 'color2', 'outindex': 0 }) self.asset_config = { 'monikers': ['blue'], 'color_set': [self.colordesc0], } self.basset_config = { 'monikers': ['bitcoin'], 'color_set': [''], } self.asset = AssetDefinition(self.colormap, self.asset_config) self.basset = AssetDefinition(self.colormap, self.basset_config) self.basic = BasicTxSpec(self.model) self.bbasic = BasicTxSpec(self.model) wam = self.model.get_address_manager() self.address0 = wam.get_new_address(self.asset.get_color_set()) self.addr0 = self.address0.get_address() self.bcolorset = ColorSet(self.colormap, ['']) self.baddress = wam.get_new_address(self.bcolorset) self.baddr = self.baddress.get_address() self.assetvalue0 = AdditiveAssetValue(asset=self.asset, value=5) self.assetvalue1 = AdditiveAssetValue(asset=self.asset, value=6) self.assetvalue2 = AdditiveAssetValue(asset=self.asset, value=7) self.bassetvalue = AdditiveAssetValue(asset=self.basset, value=8) self.assettarget0 = AssetTarget(self.addr0, self.assetvalue0) self.assettarget1 = AssetTarget(self.addr0, self.assetvalue1) self.assettarget2 = AssetTarget(self.addr0, self.assetvalue2) self.bassettarget = AssetTarget(self.baddr, self.bassetvalue) self.atargets = [ self.assettarget0, self.assettarget1, self.assettarget2 ] # add some targets self.colorvalue0 = SimpleColorValue(colordef=self.colordef0, value=5) self.colortarget0 = ColorTarget(self.addr0, self.colorvalue0) self.colorvalue1 = SimpleColorValue(colordef=self.colordef0, value=6) self.colortarget1 = ColorTarget(self.addr0, self.colorvalue1) self.colorvalue2 = SimpleColorValue(colordef=self.colordef0, value=7) self.colortarget2 = ColorTarget(self.addr0, self.colorvalue2) self.bcolorvalue = SimpleColorValue(colordef=UNCOLORED_MARKER, value=8) self.bcolortarget = ColorTarget(self.baddr, self.bcolorvalue) self.targets = [ self.colortarget0, self.colortarget1, self.colortarget2 ] self.transformer = TransactionSpecTransformer(self.model, self.config) self.blockhash = '00000000c927c5d0ee1ca362f912f83c462f644e695337ce3731b9f7c5d1ca8c' self.txhash = '4fe45a5ba31bab1e244114c4555d9070044c73c98636231c77657022d76b87f7' def test_basic(self): self.assertRaises(InvalidTargetError, self.basic.is_monocolor) self.assertRaises(InvalidTargetError, self.basic.add_target, self.colortarget0) self.basic.add_target(self.assettarget0) self.basic.add_target(self.assettarget1) self.basic.add_target(self.assettarget2) self.assertEqual(self.basic.is_monocolor(), True) self.assertEqual(self.basic.is_monoasset(), True) self.assertEqual(self.basic.targets, self.atargets) self.basic.add_target(self.bassettarget) self.assertEqual(self.basic.is_monoasset(), False) self.assertEqual(self.basic.is_monocolor(), False) self.assertRaises(InvalidTransformationError, self.basic.make_operational_tx_spec, self.asset) def add_coins(self): script = tools.compile( "OP_DUP OP_HASH160 {0} OP_EQUALVERIFY OP_CHECKSIG".format( self.address0.rawPubkey().encode("hex"))).encode("hex") self.model.utxo_man.store.add_utxo(self.addr0, self.txhash, 0, 100, script) script = tools.compile( "OP_DUP OP_HASH160 {0} OP_EQUALVERIFY OP_CHECKSIG".format( self.baddress.rawPubkey().encode("hex"))).encode("hex") self.model.utxo_man.store.add_utxo(self.baddr, self.txhash, 1, 20000, script) self.model.ccc.metastore.set_as_scanned(self.colorid0, self.blockhash) self.model.ccc.cdstore.add(self.colorid0, self.txhash, 0, 100, '') def test_operational(self): self.basic.add_target(self.assettarget0) self.basic.add_target(self.assettarget1) self.basic.add_target(self.assettarget2) op = self.transformer.transform_basic(self.basic, 'operational') self.assertTrue(self.transformer.classify_tx_spec(op), 'operational') self.assertRaises(InvalidTargetError, op.add_target, 1) self.assertEqual(ColorTarget.sum(op.get_targets()), ColorTarget.sum(self.targets)) self.assertEqual(op.get_change_addr(self.colordef0), self.addr0) self.assertEqual(op.get_change_addr(UNCOLORED_MARKER), self.baddr) self.assertEqual(op.get_required_fee(1).get_value(), 10000) self.assertRaises(InvalidColorIdError, op.get_change_addr, self.colordef1) cv = SimpleColorValue(colordef=self.colordef0, value=0) self.assertRaises(ZeroSelectError, op.select_coins, cv) cv = SimpleColorValue(colordef=self.colordef0, value=5) self.assertRaises(InsufficientFundsError, op.select_coins, cv) self.add_coins() self.assertEqual(op.select_coins(cv)[1].get_value(), 100) def test_composed(self): self.basic.add_target(self.assettarget0) self.basic.add_target(self.assettarget1) self.basic.add_target(self.assettarget2) self.add_coins() op = self.transformer.transform(self.basic, 'operational') self.assertEqual(op.get_change_addr(self.colordef0), self.addr0) self.assertEqual(op.get_change_addr(UNCOLORED_MARKER), self.baddr) comp = self.transformer.transform(op, 'composed') self.assertTrue(self.transformer.classify_tx_spec(comp), 'composed') signed = self.transformer.transform(comp, 'signed') self.assertTrue(self.transformer.classify_tx_spec(signed), 'signed') self.assertEqual(len(signed.get_hex_txhash()), 64) txdata = signed.get_tx_data() same = RawTxSpec.from_tx_data(self.model, txdata) self.assertEqual(same.get_hex_tx_data(), signed.get_hex_tx_data()) self.assertRaises(InvalidTransformationError, self.transformer.transform, signed, '') def test_other(self): self.assertEqual(self.transformer.classify_tx_spec(1), None) self.assertRaises(InvalidTransformationError, self.transformer.transform_basic, self.basic, '') self.assertRaises(InvalidTransformationError, self.transformer.transform_operational, self.basic, '') self.assertRaises(InvalidTransformationError, self.transformer.transform_composed, self.basic, '') self.assertRaises(InvalidTransformationError, self.transformer.transform_signed, self.basic, '') self.assertRaises(InvalidTransformationError, self.transformer.transform, '', '') self.add_coins() self.bbasic.add_target(self.bassettarget) signed = self.transformer.transform(self.bbasic, 'signed') self.assertEqual(len(signed.get_hex_txhash()), 64)
def setUp(self): self.path = ":memory:" self.pwallet = PersistentWallet(self.path) self.config = { 'dw_master_key': 'test', 'testnet': True, 'ccc': { 'colordb_path': self.path }, 'bip0032': False } self.pwallet.wallet_config = self.config self.pwallet.init_model() self.model = self.pwallet.get_model() self.colormap = self.model.get_color_map() self.colordesc0 = "obc:color0:0:0" self.colordesc1 = "obc:color1:0:0" self.colordesc2 = "obc:color2:0:0" # add some colordescs self.colorid0 = self.colormap.resolve_color_desc(self.colordesc0) self.colorid1 = self.colormap.resolve_color_desc(self.colordesc1) self.colorid2 = self.colormap.resolve_color_desc(self.colordesc2) self.colordef0 = OBColorDefinition(self.colorid0, { 'txhash': 'color0', 'outindex': 0 }) self.colordef1 = OBColorDefinition(self.colorid1, { 'txhash': 'color1', 'outindex': 0 }) self.colordef2 = OBColorDefinition(self.colorid2, { 'txhash': 'color2', 'outindex': 0 }) self.asset_config = { 'monikers': ['blue'], 'color_set': [self.colordesc0], } self.basset_config = { 'monikers': ['bitcoin'], 'color_set': [''], } self.asset = AssetDefinition(self.colormap, self.asset_config) self.basset = AssetDefinition(self.colormap, self.basset_config) self.basic = BasicTxSpec(self.model) self.bbasic = BasicTxSpec(self.model) wam = self.model.get_address_manager() self.address0 = wam.get_new_address(self.asset.get_color_set()) self.addr0 = self.address0.get_address() self.bcolorset = ColorSet(self.colormap, ['']) self.baddress = wam.get_new_address(self.bcolorset) self.baddr = self.baddress.get_address() self.assetvalue0 = AdditiveAssetValue(asset=self.asset, value=5) self.assetvalue1 = AdditiveAssetValue(asset=self.asset, value=6) self.assetvalue2 = AdditiveAssetValue(asset=self.asset, value=7) self.bassetvalue = AdditiveAssetValue(asset=self.basset, value=8) self.assettarget0 = AssetTarget(self.addr0, self.assetvalue0) self.assettarget1 = AssetTarget(self.addr0, self.assetvalue1) self.assettarget2 = AssetTarget(self.addr0, self.assetvalue2) self.bassettarget = AssetTarget(self.baddr, self.bassetvalue) self.atargets = [ self.assettarget0, self.assettarget1, self.assettarget2 ] # add some targets self.colorvalue0 = SimpleColorValue(colordef=self.colordef0, value=5) self.colortarget0 = ColorTarget(self.addr0, self.colorvalue0) self.colorvalue1 = SimpleColorValue(colordef=self.colordef0, value=6) self.colortarget1 = ColorTarget(self.addr0, self.colorvalue1) self.colorvalue2 = SimpleColorValue(colordef=self.colordef0, value=7) self.colortarget2 = ColorTarget(self.addr0, self.colorvalue2) self.bcolorvalue = SimpleColorValue(colordef=UNCOLORED_MARKER, value=8) self.bcolortarget = ColorTarget(self.baddr, self.bcolorvalue) self.targets = [ self.colortarget0, self.colortarget1, self.colortarget2 ] self.transformer = TransactionSpecTransformer(self.model, self.config) self.blockhash = '00000000c927c5d0ee1ca362f912f83c462f644e695337ce3731b9f7c5d1ca8c' self.txhash = '4fe45a5ba31bab1e244114c4555d9070044c73c98636231c77657022d76b87f7'
class TestAgent(unittest.TestCase): def setUp(self): self.path = ":memory:" self.config = { "hdw_master_key": "91813223e97697c42f05e54b3a85bae601f04526c5c053ff0811747db77cfdf5f1accb50b3765377c379379cd5aa512c38bf24a57e4173ef592305d16314a0f4", "testnet": True, "ccc": {"colordb_path": self.path}, } self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() self.wc = WalletController(self.model) self.ewc = EWalletController(self.model, self.wc) self.econfig = {"offer_expiry_interval": 30, "ep_expiry_interval": 30} self.comm0 = MockComm() self.comm1 = MockComm() self.comm0.add_peer(self.comm1) self.comm1.add_peer(self.comm0) self.agent0 = EAgent(self.ewc, self.econfig, self.comm0) self.agent1 = EAgent(self.ewc, self.econfig, self.comm1) self.cspec = "obc:03524a4d6492e8d43cb6f3906a99be5a1bcd93916241f759812828b301f25a6c:0:153267" def add_coins(self): self.config["asset_definitions"] = [ {"color_set": [""], "monikers": ["bitcoin"], "unit": 100000000}, {"color_set": [self.cspec], "monikers": ["test"], "unit": 1}, ] self.config["hdwam"] = { "genesis_color_sets": [[self.cspec]], "color_set_states": [{"color_set": [""], "max_index": 1}, {"color_set": [self.cspec], "max_index": 7}], } self.config["bip0032"] = True self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() self.ewc.model = self.model self.wc.model = self.model def null(a): pass self.wc.publish_tx = null # modify model colored coin context, so test runs faster ccc = self.model.ccc cdbuilder = ColorDataBuilderManager( ccc.colormap, ccc.blockchain_state, ccc.cdstore, ccc.metastore, AidedColorDataBuilder ) ccc.colordata = ThinColorData(cdbuilder, ccc.blockchain_state, ccc.cdstore, ccc.colormap) # need to query the blockchain self.model.utxo_man.update_all() adm = self.model.get_asset_definition_manager() asset = adm.get_asset_by_moniker("test") cq = self.model.make_coin_query({"asset": asset}) utxo_list = cq.get_result() self.cd = ColorDefinition.from_color_desc(1, self.cspec) self.cv0 = SimpleColorValue(colordef=UNCOLORED_MARKER, value=100) self.cv1 = SimpleColorValue(colordef=self.cd, value=200) self.offer0 = MyEOffer(None, self.cv0, self.cv1) self.offer1 = MyEOffer(None, self.cv1, self.cv0) def test_set_event_handler(self): tmp = {"test": 0} def handler(val): tmp["test"] = val self.agent0.set_event_handler("click", handler) self.agent0.fire_event("click", 7) self.assertEqual(tmp["test"], 7) self.agent0.ep_timeout = time.time() - 100 self.assertFalse(self.agent0.has_active_ep()) def test_real(self): self.add_coins() self.assertFalse(self.agent0.has_active_ep()) self.agent0.register_my_offer(self.offer0) self.agent1.register_my_offer(self.offer1) for i in range(3): self.agent0._update_state() self.agent1._update_state() self.assertFalse(self.agent0.has_active_ep()) self.assertFalse(self.agent1.has_active_ep()) m0 = self.comm0.get_messages() m1 = self.comm1.get_messages() self.assertEquals(len(m0), 2) self.assertEquals(len(m1), 2) self.assertEquals(self.offer0.get_data(), m0[1]["offer"]) self.assertEquals(self.offer0.get_data(), m1[1]["offer"]) # expire offers offer2 = MyEOffer(None, self.cv0, self.cv1) self.agent0.register_my_offer(offer2) self.agent0.update() self.agent0.update() self.agent1.update() self.agent0.cancel_my_offer(offer2) self.agent0.update() self.agent1.update() self.assertFalse(self.agent0.has_active_ep()) self.assertFalse(self.agent1.has_active_ep()) offer3 = MyEOffer(None, self.cv1, self.cv0) self.agent0.make_exchange_proposal(offer3, offer2) self.assertRaises(Exception, self.agent0.make_exchange_proposal, offer3, offer2) ep = MyEProposal(self.ewc, offer3, offer2) def raiseException(x): raise Exception() self.agent0.set_event_handler("accept_ep", raiseException) # methods that should do nothing now that we have an active ep self.agent0.accept_exchange_proposal(ep) self.agent0.match_offers() self.agent0.register_their_offer(offer3) self.agent0.accept_exchange_proposal(ep) ep2 = MyEProposal(self.ewc, offer3, offer2) self.agent0.dispatch_exchange_proposal(ep2.get_data()) # test a few corner cases self.agent0.register_my_offer(offer2) offer2.refresh(-1000) self.assertTrue(offer2.expired()) self.agent0.service_my_offers() self.agent0.cancel_my_offer(offer2) self.agent0.register_their_offer(offer3) offer3.refresh(-1000) self.agent0.service_their_offers()
class Wallet(object): thread_comm = None def __init__(self): parser = argparse.ArgumentParser() parser.add_argument("--wallet", dest="wallet_path") parsed_args = vars(parser.parse_args()) self.wallet = PersistentWallet(parsed_args.get('wallet_path')) self.wallet.init_model() self.model = self.wallet.get_model() self.controller = WalletController(self.wallet.get_model()) def get_asset_definition(self, moniker): if isinstance(moniker, AssetDefinition): return moniker adm = self.wallet.get_model().get_asset_definition_manager() asset = adm.get_asset_by_moniker(moniker) if asset: return asset else: raise Exception("asset not found") def get_asset_definition_by_color_set(self, color_set): adm = self.wallet.get_model().get_asset_definition_manager() for asset in adm.get_all_assets(): if color_set in asset.get_color_set().get_data(): return asset raise Exception("asset not found") def add_asset(self, params): self.controller.add_asset_definition({ "monikers": [params['moniker']], "color_set": [params['color_desc']], "unit": params['unit'] }) if len(self.get_all_addresses(params['moniker'])) == 0: self.get_new_address(params['moniker']) def get_all_asset(self): return self.wallet.wallet_config['asset_definitions'] def issue(self, params): self.controller.issue_coins( params['moniker'], params['coloring_scheme'], params['units'], params['atoms']) if len(self.get_all_addresses(params['moniker'])) == 0: self.get_new_address(params['moniker']) def get_all_monikers(self): monikers = [asset.get_monikers()[0] for asset in self.model.get_asset_definition_manager().get_all_assets()] monikers.remove('bitcoin') monikers = ['bitcoin'] + monikers return monikers def get_balance(self, color): return self.controller.get_balance(self.get_asset_definition(color)) def get_all_addresses(self, color): return [addr.get_color_address() for addr in self.controller.get_all_addresses(self.get_asset_definition(color))] def get_address_balance(self, color): asset = self.get_asset_definition(color) return self.controller.get_address_balance(asset) def get_some_address(self, color): wam = self.model.get_address_manager() cs = self.get_asset_definition(color).get_color_set() ar = wam.get_some_address(cs) return ar.get_color_address() def get_new_address(self, color): return self.controller. \ get_new_address(self.get_asset_definition(color)).get_color_address() def scan(self): self.controller.scan_utxos() def send_coins(self, items): if isinstance(items, dict): items = [items] for item in items: self.controller.send_coins( item['asset'] if 'asset' in item \ else self.get_asset_definition(item['moniker']), [item['address']], [item['value']]) def p2ptrade_init(self): ewctrl = EWalletController(self.model, self.controller) config = {"offer_expiry_interval": 30, "ep_expiry_interval": 30} comm = HTTPComm( config, 'http://p2ptrade.btx.udoidio.info/messages') self.thread_comm = ThreadedComm(comm) self.p2p_agent = EAgent(ewctrl, config, self.thread_comm) self.thread_comm.start() def p2ptrade_stop(self): if self.thread_comm is not None: self.thread_comm.stop() def p2ptrade_make_offer(self, we_sell, params): asset = self.get_asset_definition(params['moniker']) value = asset.parse_value(params['value']) bitcoin = self.get_asset_definition('bitcoin') price = bitcoin.parse_value(params['price']) total = int(float(value)/float(asset.unit)*float(price)) color_desc = asset.get_color_set().color_desc_list[0] sell_side = {"color_spec": color_desc, "value": value} buy_side = {"color_spec": "", "value": total} if we_sell: return MyEOffer(None, sell_side, buy_side) else: return MyEOffer(None, buy_side, sell_side) def p2ptrade_make_mirror_offer(self, offer): data = offer.get_data() return MyEOffer(None, data['B'], data['A'], False)
class TestEWalletController(unittest.TestCase): def setUp(self): self.pwallet = PersistentWallet(None, True) self.pwallet.init_model() self.model = self.pwallet.get_model() adm = self.model.get_asset_definition_manager() # make sure you have the asset 'testobc' in your testnet.wallet !! self.asset = adm.get_asset_by_moniker('testobc') self.color_spec = self.asset.get_color_set().get_data()[0] self.wc = WalletController(self.model) self.ewc = EWalletController(self.model, self.wc) def null(a): pass self.wc.publish_tx = null def test_resolve_color_spec(self): self.cd = self.ewc.resolve_color_spec('') self.assertRaises(KeyError, self.ewc.resolve_color_spec, 'nonexistent') self.assertTrue(isinstance(self.cd, ColorDefinition)) self.assertEqual(self.cd.get_color_id(), 0) def test_select_inputs(self): cv = SimpleColorValue(colordef=UNCOLORED_MARKER, value=10000000000000) self.assertRaises(InsufficientFundsError, self.ewc.select_inputs, cv) def test_tx_spec(self): alice_cv = {'color_spec': self.color_spec, 'value': 10} bob_cv = {'color_spec': "", 'value': 500} alice_offer = MyEOffer(None, alice_cv, bob_cv) bob_offer = MyEOffer(None, bob_cv, alice_cv) bob_etx = self.ewc.make_etx_spec(bob_cv, alice_cv) self.assertTrue(isinstance(bob_etx, ETxSpec)) for target in bob_etx.targets: # check address address = target[0] self.assertTrue(isinstance(address, type(u"unicode"))) # TODO check address is correct format # check color_spec color_spec = target[1] self.assertTrue(isinstance(color_spec, type("str"))) color_spec_parts = len(color_spec.split(":")) self.assertTrue(color_spec_parts == 4 or color_spec_parts == 1) # check value value = target[2] self.assertTrue(isinstance(value, type(10))) signed = self.ewc.make_reply_tx(bob_etx, alice_cv, bob_cv) self.assertTrue(isinstance(signed, RawTxSpec)) self.ewc.publish_tx(signed, alice_offer) alice_etx = self.ewc.make_etx_spec(alice_cv, bob_cv) self.assertTrue(isinstance(alice_etx, ETxSpec)) for target in alice_etx.targets: # check address address = target[0] self.assertTrue(isinstance(address, type(u"unicode"))) # TODO check address is correct format # check color_spec color_spec = target[1] self.assertTrue(isinstance(color_spec, type("str"))) color_spec_parts = len(color_spec.split(":")) self.assertTrue(color_spec_parts == 4 or color_spec_parts == 1) # check value value = target[2] self.assertTrue(isinstance(value, type(10))) signed = self.ewc.make_reply_tx(alice_etx, bob_cv, alice_cv) self.assertTrue(isinstance(signed, RawTxSpec)) oets = OperationalETxSpec(self.model, self.ewc) oets.set_our_value_limit(bob_cv) oets.prepare_inputs(alice_etx) zero = SimpleColorValue(colordef=UNCOLORED_MARKER, value=0) self.assertRaises(ZeroSelectError, oets.select_coins, zero) toomuch = SimpleColorValue(colordef=UNCOLORED_MARKER, value=10000000000000) self.assertRaises(InsufficientFundsError, oets.select_coins, toomuch)
class Ngccc(apigen.Definition): """Next-Generation Colored Coin Client interface.""" def __init__(self, wallet=None, testnet=False): # sanitize inputs testnet = sanitize.flag(testnet) if not wallet: wallet = "%s.wallet" % ("testnet" if testnet else "mainnet") self.wallet = PersistentWallet(wallet, testnet) self.wallet.init_model() self.model = self.wallet.get_model() self.controller = WalletController(self.model) @apigen.command() def setconfigval(self, key, value): # FIXME behaviour ok? """Sets a value in the configuration. Key is expressed as: key.subkey.subsubkey """ # sanitize inputs key = sanitize.cfgkey(key) value = sanitize.cfgvalue(value) kpath = key.split('.') value = json.loads(value) # traverse the path until we get to the value we need to set if len(kpath) > 1: branch = self.wallet.wallet_config[kpath[0]] cdict = branch for k in kpath[1:-1]: cdict = cdict[k] cdict[kpath[-1]] = value value = branch if kpath[0] in self.wallet.wallet_config: self.wallet.wallet_config[kpath[0]] = value else: raise KeyNotFound(key) @apigen.command() def getconfigval(self, key): """Returns the value for a given key in the config. Key is expressed as: key.subkey.subsubkey """ # sanitize inputs key = sanitize.cfgkey(key) if not key: raise KeyNotFound(key) keys = key.split('.') config = self.wallet.wallet_config # traverse the path until we get the value for key in keys: config = config[key] return _print(config) @apigen.command() def dumpconfig(self): """Returns a dump of the current configuration.""" dict_config = dict(self.wallet.wallet_config.iteritems()) return _print(dict_config) @apigen.command() def importconfig(self, path): # FIXME what about subkeys and removed keys? """Import JSON config.""" with open(path, 'r') as fp: config = json.loads(fp.read()) wallet_config = self.wallet.wallet_config for k in config: wallet_config[k] = config[k] @apigen.command() def issueasset(self, moniker, quantity, unit="100000000", scheme="epobc"): """ Issue <quantity> of asset with name <moniker> and <unit> atoms, based on <scheme (epobc|obc)>.""" # sanitize inputs moniker = sanitize.moniker(moniker) quantity = sanitize.quantity(quantity) unit = sanitize.unit(unit) scheme = sanitize.scheme(scheme) self.controller.issue_coins(moniker, scheme, quantity, unit) return self.getasset(moniker) @apigen.command() def addassetjson(self, data): """Add a json asset definition. Enables the use of colors/assets issued by others. """ # sanitize inputs data = sanitize.jsonasset(data) self.controller.add_asset_definition(data) return self.getasset(data['monikers'][0]) @apigen.command() def addasset(self, moniker, color_description, unit=100000000): """Add a asset definition. Enables the use of colors/assets issued by others. """ # sanitize inputs moniker = sanitize.moniker(moniker) color_description = sanitize.colordesc(color_description) unit = sanitize.unit(unit) self.controller.add_asset_definition({ "monikers": [moniker], "color_set": [color_description], "unit": unit }) return self.getasset(moniker) @apigen.command() def getasset(self, moniker): """Get the asset associated with the moniker.""" return _print(sanitize.asset(self.model, moniker).get_data()) @apigen.command() def listassets(self): """Lists all assets/colors registered.""" assets = self.controller.get_all_assets() return _print(map(lambda asset: asset.get_data(), assets)) def _getbalance(self, asset, unconfirmed, available): if unconfirmed: balance = self.controller.get_unconfirmed_balance(asset) elif available: balance = self.controller.get_available_balance(asset) else: balance = self.controller.get_total_balance(asset) return (asset.get_monikers()[0], asset.format_value(balance)) @apigen.command() def getbalance(self, moniker, unconfirmed=False, available=False): """Returns the balance for a particular asset.""" # sanitize inputs asset = sanitize.asset(self.model, moniker) unconfirmed = sanitize.flag(unconfirmed) available = sanitize.flag(available) balance = dict([self._getbalance(asset, unconfirmed, available)]) return _print(balance) @apigen.command() def getbalances(self, unconfirmed=False, available=False): """Returns the balances for all assets/colors.""" # sanitize inputs unconfirmed = sanitize.flag(unconfirmed) available = sanitize.flag(available) assets = self.controller.get_all_assets() func = lambda asset: self._getbalance(asset, unconfirmed, available) balances = dict(map(func, assets)) return _print(balances) @apigen.command() def newaddress(self, moniker): """Creates a new coloraddress for a given asset.""" # sanitize inputs asset = sanitize.asset(self.model, moniker) addressrecord = self.controller.get_new_address(asset) coloraddress = addressrecord.get_color_address() return _print(coloraddress) @apigen.command() def listaddresses(self, moniker): """Lists all addresses for a given asset""" # sanitize inputs asset = sanitize.asset(self.model, moniker) addressrecords = self.controller.get_all_addresses(asset) return _print([ao.get_color_address() for ao in addressrecords]) @apigen.command() def send(self, moniker, coloraddress, amount): """Send <coloraddress> given <amount> of an asset.""" # sanitize inputs asset = sanitize.asset(self.model, moniker) coloraddress = sanitize.coloraddress(self.model, asset, coloraddress) amount = sanitize.assetamount(asset, amount) txid = self.controller.send_coins(asset, [coloraddress], [amount]) return _print(txid) @apigen.command() def sendmanyjson(self, data): """Send amounts given in json fromatted data. Format [{'moniker':"val",'amount':"val",'coloraddress':"val"}] All entries must use the same color scheme. """ # sanitize inputs sendmany_entries = sanitize.sendmanyjson(self.model, data) return _print(self.controller.sendmany_coins(sendmany_entries)) @apigen.command() def sendmanycsv(self, path): """Send amounts in csv file with format 'moniker,coloraddress,amount'. All entries must use the same color scheme. """ # sanitize inputs sendmany_entries = sanitize.sendmanycsv(self.model, path) return _print(self.controller.sendmany_coins(sendmany_entries)) @apigen.command() def scan(self): """Update the database of transactions.""" sleep(5) self.controller.scan_utxos() @apigen.command() def fullrescan(self): """Rebuild database of wallet transactions.""" self.controller.full_rescan() @apigen.command() def history(self, moniker): """Show the history of transactions for given asset.""" # sanitize inputs asset = sanitize.asset(self.model, moniker) return _print(self.controller.get_history(asset)) @apigen.command() def received(self, moniker): """Returns total received amount for each coloraddress of a given asset. """ # sanitize inputs asset = sanitize.asset(self.model, moniker) received = {} def reformat(data): coloraddress = data['color_address'] colorvalue = data['value'].get_value() return (coloraddress, asset.format_value(colorvalue)) data = self.controller.get_received_by_address(asset) return _print(dict(map(reformat, data))) @apigen.command() def coinlog(self): """Returns the coin transaction log for this wallet.""" log = defaultdict(list) for coin in self.controller.get_coinlog(): moniker = coin.asset.get_monikers()[0] moniker = 'bitcoin' if moniker == '' else moniker log[moniker].append({ 'address': coin.get_address(), 'txid': coin.txhash, 'out': coin.outindex, 'colorvalue': coin.colorvalues[0].get_value(), 'value': coin.value, 'confirmed': coin.is_confirmed(), 'spendingtxs': coin.get_spending_txs(), }) return _print(log) @apigen.command() def dumpprivkey(self, moniker, coloraddress): """Private key for a given coloraddress.""" # sanitize inputs asset = sanitize.asset(self.model, moniker) coloraddress = sanitize.coloraddress(self.model, asset, coloraddress) wam = self.model.get_address_manager() for addressrecord in wam.get_all_addresses(): if coloraddress == addressrecord.get_color_address(): return _print(addressrecord.get_private_key()) raise AddressNotFound(coloraddress) @apigen.command() def dumpprivkeys(self, moniker): """Lists all private keys for a given asset.""" # sanitize inputs asset = sanitize.asset(self.model, moniker) addressrecords = self.controller.get_all_addresses(asset) return _print(map(lambda ar: ar.get_private_key(), addressrecords)) def _init_p2ptrade(self): ewctrl = EWalletController(self.model, self.controller) config = {"offer_expiry_interval": 30, "ep_expiry_interval": 30} comm = HTTPComm(config, 'http://p2ptrade.btx.udoidio.info/messages') return EAgent(ewctrl, config, comm) def _p2ptrade_make_offer(self, we_sell, moniker, value, price, wait): # sanitize inputs asset = sanitize.asset(self.model, moniker) bitcoin = sanitize.asset(self.model, 'bitcoin') value = sanitize.assetamount(asset, value) price = sanitize.assetamount(bitcoin, price) wait = sanitize.integer(wait) total = int(Decimal(value) / Decimal(asset.unit) * Decimal(price)) color_desc = asset.get_color_set().color_desc_list[0] sell_side = {"color_spec": color_desc, "value": value} buy_side = {"color_spec": "", "value": total} agent = self._init_p2ptrade() if we_sell: agent.register_my_offer(MyEOffer(None, sell_side, buy_side)) else: agent.register_my_offer(MyEOffer(None, buy_side, sell_side)) self._p2ptrade_wait(agent, wait) def _p2ptrade_wait(self, agent, wait): if wait and wait > 0: for _ in xrange(wait): agent.update() sleep(1) else: for _ in xrange(4 * 6): agent.update() sleep(0.25) @apigen.command() def p2porders(self, moniker="", sellonly=False, buyonly=False): """Show peer to peer trade orders""" # sanitize inputs sellonly = sanitize.flag(sellonly) buyonly = sanitize.flag(buyonly) asset = None if moniker and moniker != 'bitcoin': asset = sanitize.asset(self.model, moniker) # get offers agent = self._init_p2ptrade() agent.update() offers = agent.their_offers.values() offers = map(lambda offer: offer.get_data(), offers) # filter asset if given if asset: descs = asset.get_color_set().color_desc_list def func(offer): return (offer["A"]["color_spec"] in descs or offer["B"]["color_spec"] in descs) offers = filter(func, offers) # filter sellonly if given if sellonly: offers = filter(lambda o: o["A"]["color_spec"] != "", offers) # filter buyonly if given if buyonly: offers = filter(lambda o: o["A"]["color_spec"] == "", offers) return _print(offers) @apigen.command() def p2psell(self, moniker, assetamount, btcprice, wait=30): """Sell <assetamount> for <btcprice> via peer to peer trade.""" self._p2ptrade_make_offer(True, moniker, assetamount, btcprice, wait) @apigen.command() def p2pbuy(self, moniker, assetamount, btcprice, wait=30): """Buy <assetamount> for <btcprice> via peer to peer trade.""" self._p2ptrade_make_offer(False, moniker, assetamount, btcprice, wait)
class TestAgent(unittest.TestCase): def setUp(self): self.path = ":memory:" self.config = { 'hdw_master_key': '91813223e97697c42f05e54b3a85bae601f04526c5c053ff0811747db77cfdf5f1accb50b3765377c379379cd5aa512c38bf24a57e4173ef592305d16314a0f4', 'testnet': True, 'ccc': { 'colordb_path': self.path }, } self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() self.wc = WalletController(self.model) self.ewc = EWalletController(self.model, self.wc) self.econfig = {"offer_expiry_interval": 30, "ep_expiry_interval": 30} self.comm0 = MockComm() self.comm1 = MockComm() self.comm0.add_peer(self.comm1) self.comm1.add_peer(self.comm0) self.agent0 = EAgent(self.ewc, self.econfig, self.comm0) self.agent1 = EAgent(self.ewc, self.econfig, self.comm1) self.cspec = "obc:03524a4d6492e8d43cb6f3906a99be5a1bcd93916241f759812828b301f25a6c:0:153267" def add_coins(self): self.config['asset_definitions'] = [ { "color_set": [""], "monikers": ["bitcoin"], "unit": 100000000 }, { "color_set": [self.cspec], "monikers": ['test'], "unit": 1 }, ] self.config['hdwam'] = { "genesis_color_sets": [ [self.cspec], ], "color_set_states": [ { "color_set": [""], "max_index": 1 }, { "color_set": [self.cspec], "max_index": 7 }, ] } self.config['bip0032'] = True self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() self.ewc.model = self.model self.wc.model = self.model def null(a): pass self.wc.publish_tx = null # modify model colored coin context, so test runs faster ccc = self.model.ccc cdbuilder = ColorDataBuilderManager(ccc.colormap, ccc.blockchain_state, ccc.cdstore, ccc.metastore, AidedColorDataBuilder) ccc.colordata = ThinColorData(cdbuilder, ccc.blockchain_state, ccc.cdstore, ccc.colormap) # need to query the blockchain self.model.utxo_man.update_all() adm = self.model.get_asset_definition_manager() asset = adm.get_asset_by_moniker('test') cq = self.model.make_coin_query({"asset": asset}) utxo_list = cq.get_result() self.cd = ColorDefinition.from_color_desc(1, self.cspec) self.cv0 = SimpleColorValue(colordef=UNCOLORED_MARKER, value=100) self.cv1 = SimpleColorValue(colordef=self.cd, value=200) self.offer0 = MyEOffer(None, self.cv0, self.cv1) self.offer1 = MyEOffer(None, self.cv1, self.cv0) def test_set_event_handler(self): tmp = {'test': 0} def handler(val): tmp['test'] = val self.agent0.set_event_handler('click', handler) self.agent0.fire_event('click', 7) self.assertEqual(tmp['test'], 7) self.agent0.ep_timeout = time.time() - 100 self.assertFalse(self.agent0.has_active_ep()) def test_real(self): self.add_coins() self.assertFalse(self.agent0.has_active_ep()) self.agent0.register_my_offer(self.offer0) self.agent1.register_my_offer(self.offer1) for i in range(3): self.agent0._update_state() self.agent1._update_state() self.assertFalse(self.agent0.has_active_ep()) self.assertFalse(self.agent1.has_active_ep()) m0 = self.comm0.get_messages() m1 = self.comm1.get_messages() self.assertEquals(len(m0), 2) self.assertEquals(len(m1), 2) self.assertEquals(self.offer0.get_data(), m0[1]['offer']) self.assertEquals(self.offer0.get_data(), m1[1]['offer']) # expire offers offer2 = MyEOffer(None, self.cv0, self.cv1) self.agent0.register_my_offer(offer2) self.agent0.update() self.agent0.update() self.agent1.update() self.agent0.cancel_my_offer(offer2) self.agent0.update() self.agent1.update() self.assertFalse(self.agent0.has_active_ep()) self.assertFalse(self.agent1.has_active_ep()) offer3 = MyEOffer(None, self.cv1, self.cv0) self.agent0.make_exchange_proposal(offer3, offer2) self.assertRaises(Exception, self.agent0.make_exchange_proposal, offer3, offer2) ep = MyEProposal(self.ewc, offer3, offer2) def raiseException(x): raise Exception() self.agent0.set_event_handler('accept_ep', raiseException) # methods that should do nothing now that we have an active ep self.agent0.accept_exchange_proposal(ep) self.agent0.match_offers() self.agent0.register_their_offer(offer3) self.agent0.accept_exchange_proposal(ep) ep2 = MyEProposal(self.ewc, offer3, offer2) self.agent0.dispatch_exchange_proposal(ep2.get_data()) # test a few corner cases self.agent0.register_my_offer(offer2) offer2.refresh(-1000) self.assertTrue(offer2.expired()) self.agent0.service_my_offers() self.agent0.cancel_my_offer(offer2) self.agent0.register_their_offer(offer3) offer3.refresh(-1000) self.agent0.service_their_offers()
class Wallet(object): thread_comm = None def __init__(self): parser = argparse.ArgumentParser() parser.add_argument("--wallet", dest="wallet_path") parser.add_argument("--testnet", action='store_true') parsed_args = vars(parser.parse_args()) self.wallet = PersistentWallet(parsed_args.get('wallet_path'), parsed_args.get('testnet')) self.wallet.init_model() self.model = self.wallet.get_model() self.controller = WalletController(self.wallet.get_model()) self.async_utxo_fetcher = AsyncUTXOFetcher( self.model, self.wallet.wallet_config.get('utxo_fetcher', {})) self.update_connected_thread = TimedAsyncTask(self.update_connected, 2.5) self.update_connected_thread.start() self.update_connected() def connected(self): return self.is_connected def update_connected(self): try: for moniker in self.get_all_monikers(): asset = self.get_asset_definition(moniker) address = self.get_some_address(asset) total_balance = self.get_total_balance(asset) self.is_connected = self.async_utxo_fetcher.interface.connected() except: raise self.is_connected = False def get_asset_definition(self, moniker): if isinstance(moniker, AssetDefinition): return moniker adm = self.wallet.get_model().get_asset_definition_manager() asset = adm.get_asset_by_moniker(moniker) if asset: return asset else: raise Exception("Asset '%s' not found!" % moniker) def get_asset_definition_by_color_set(self, color_set): adm = self.wallet.get_model().get_asset_definition_manager() for asset in adm.get_all_assets(): if color_set in asset.get_color_set().get_data(): return asset raise Exception("Asset not found!") def add_asset(self, params): self.controller.add_asset_definition({ "monikers": [params['moniker']], "color_set": [params['color_desc']], "unit": params['unit'] }) if len(self.get_all_addresses(params['moniker'])) == 0: self.get_new_address(params['moniker']) def get_all_asset(self): return self.wallet.wallet_config['asset_definitions'] def issue(self, params): self.controller.issue_coins( params['moniker'], params['coloring_scheme'], params['units'], params['atoms']) if len(self.get_all_addresses(params['moniker'])) == 0: self.get_new_address(params['moniker']) def get_all_monikers(self): monikers = [asset.get_monikers()[0] for asset in self.model.get_asset_definition_manager().get_all_assets()] monikers.remove('bitcoin') monikers = ['bitcoin'] + monikers return monikers def get_available_balance(self, color): return self.controller.get_available_balance( self.get_asset_definition(color)) def get_total_balance(self, color): return self.controller.get_total_balance( self.get_asset_definition(color)) def get_unconfirmed_balance(self, color): return self.controller.get_unconfirmed_balance( self.get_asset_definition(color)) def get_all_addresses(self, color): return [addr.get_color_address() for addr in self.controller.get_all_addresses(self.get_asset_definition(color))] def get_received_by_address(self, color): asset = self.get_asset_definition(color) return self.controller.get_received_by_address(asset) def get_some_address(self, color): wam = self.model.get_address_manager() cs = self.get_asset_definition(color).get_color_set() ar = wam.get_some_address(cs) return ar.get_color_address() def get_new_address(self, color): return self.controller. \ get_new_address(self.get_asset_definition(color)).get_color_address() def scan(self): self.controller.scan_utxos() def send_coins(self, items): if isinstance(items, dict): items = [items] for item in items: self.controller.send_coins( item['asset'] if 'asset' in item \ else self.get_asset_definition(item['moniker']), [item['address']], [item['value']]) def p2ptrade_init(self): ewctrl = EWalletController(self.model, self.controller) config = {"offer_expiry_interval": 30, "ep_expiry_interval": 30} self.thread_comm = ThreadedComm( config, 'http://p2ptrade.btx.udoidio.info/messages' ) self.p2p_agent = EAgent(ewctrl, config, self.thread_comm) self.thread_comm.start() def p2ptrade_stop(self): if self.thread_comm is not None: self.thread_comm.stop() def p2ptrade_make_offer(self, we_sell, params): asset = self.get_asset_definition(params['moniker']) value = asset.parse_value(params['value']) bitcoin = self.get_asset_definition('bitcoin') price = bitcoin.parse_value(params['price']) total = int(Decimal(value)/Decimal(asset.unit)*Decimal(price)) color_desc = asset.get_color_set().color_desc_list[0] sell_side = {"color_spec": color_desc, "value": value} buy_side = {"color_spec": "", "value": total} if we_sell: return MyEOffer(None, sell_side, buy_side) else: return MyEOffer(None, buy_side, sell_side) def p2ptrade_make_mirror_offer(self, offer): data = offer.get_data() return MyEOffer(None, data['B'], data['A']) def stop_all(self): self.update_connected_thread.stop() self.update_connected_thread.join() self.async_utxo_fetcher.stop() self.p2ptrade_stop() if hasattr(self.model.txdb, 'vbs'): self.model.txdb.vbs.stop()
class Wallet(object): thread_comm = None def __init__(self): parser = argparse.ArgumentParser() parser.add_argument("--wallet", dest="wallet_path") parser.add_argument("--testnet", action='store_true') parsed_args = vars(parser.parse_args()) self.wallet = PersistentWallet(parsed_args.get('wallet_path'), parsed_args.get('testnet')) self.wallet.init_model() self.model = self.wallet.get_model() self.controller = WalletController(self.wallet.get_model()) self.async_utxo_fetcher = AsyncUTXOFetcher( self.model, self.wallet.wallet_config.get('utxo_fetcher', {})) def get_asset_definition(self, moniker): if isinstance(moniker, AssetDefinition): return moniker adm = self.wallet.get_model().get_asset_definition_manager() asset = adm.get_asset_by_moniker(moniker) if asset: return asset else: raise Exception("asset not found") def get_asset_definition_by_color_set(self, color_set): adm = self.wallet.get_model().get_asset_definition_manager() for asset in adm.get_all_assets(): if color_set in asset.get_color_set().get_data(): return asset raise Exception("asset not found") def add_asset(self, params): self.controller.add_asset_definition({ "monikers": [params['moniker']], "color_set": [params['color_desc']], "unit": params['unit'] }) if len(self.get_all_addresses(params['moniker'])) == 0: self.get_new_address(params['moniker']) def get_all_asset(self): return self.wallet.wallet_config['asset_definitions'] def issue(self, params): self.controller.issue_coins( params['moniker'], params['coloring_scheme'], params['units'], params['atoms']) if len(self.get_all_addresses(params['moniker'])) == 0: self.get_new_address(params['moniker']) def get_all_monikers(self): monikers = [asset.get_monikers()[0] for asset in self.model.get_asset_definition_manager().get_all_assets()] monikers.remove('bitcoin') monikers = ['bitcoin'] + monikers return monikers def get_available_balance(self, color): return self.controller.get_available_balance( self.get_asset_definition(color)) def get_total_balance(self, color): return self.controller.get_total_balance( self.get_asset_definition(color)) def get_unconfirmed_balance(self, color): return self.controller.get_unconfirmed_balance( self.get_asset_definition(color)) def get_all_addresses(self, color): return [addr.get_color_address() for addr in self.controller.get_all_addresses(self.get_asset_definition(color))] def get_received_by_address(self, color): asset = self.get_asset_definition(color) return self.controller.get_received_by_address(asset) def get_some_address(self, color): wam = self.model.get_address_manager() cs = self.get_asset_definition(color).get_color_set() ar = wam.get_some_address(cs) return ar.get_color_address() def get_new_address(self, color): return self.controller. \ get_new_address(self.get_asset_definition(color)).get_color_address() def scan(self): self.controller.scan_utxos() def send_coins(self, items): if isinstance(items, dict): items = [items] for item in items: self.controller.send_coins( item['asset'] if 'asset' in item \ else self.get_asset_definition(item['moniker']), [item['address']], [item['value']]) def p2ptrade_init(self): ewctrl = EWalletController(self.model, self.controller) config = {"offer_expiry_interval": 30, "ep_expiry_interval": 30} comm = HTTPComm( config, 'http://p2ptrade.btx.udoidio.info/messages') self.thread_comm = ThreadedComm(comm) self.p2p_agent = EAgent(ewctrl, config, self.thread_comm) self.thread_comm.start() def p2ptrade_stop(self): if self.thread_comm is not None: self.thread_comm.stop() def p2ptrade_make_offer(self, we_sell, params): asset = self.get_asset_definition(params['moniker']) value = asset.parse_value(params['value']) bitcoin = self.get_asset_definition('bitcoin') price = bitcoin.parse_value(params['price']) total = int(float(value)/float(asset.unit)*float(price)) color_desc = asset.get_color_set().color_desc_list[0] sell_side = {"color_spec": color_desc, "value": value} buy_side = {"color_spec": "", "value": total} if we_sell: return MyEOffer(None, sell_side, buy_side) else: return MyEOffer(None, buy_side, sell_side) def p2ptrade_make_mirror_offer(self, offer): data = offer.get_data() return MyEOffer(None, data['B'], data['A'], False) def stop_all(self): self.async_utxo_fetcher.stop() self.p2ptrade_stop() if hasattr(self.model.txdb, 'vbs'): self.model.txdb.vbs.stop()
class TestTxcons(unittest.TestCase): def setUp(self): self.path = ":memory:" self.pwallet = PersistentWallet(self.path) self.config = {'dw_master_key': 'test', 'testnet': True, 'ccc': { 'colordb_path' : self.path}, 'bip0032': False } self.pwallet.wallet_config = self.config self.pwallet.init_model() self.model = self.pwallet.get_model() self.colormap = self.model.get_color_map() self.colordesc0 = "obc:color0:0:0" self.colordesc1 = "obc:color1:0:0" self.colordesc2 = "obc:color2:0:0" # add some colordescs self.colorid0 = self.colormap.resolve_color_desc(self.colordesc0) self.colorid1 = self.colormap.resolve_color_desc(self.colordesc1) self.colorid2 = self.colormap.resolve_color_desc(self.colordesc2) self.colordef0 = OBColorDefinition( self.colorid0, {'txhash': 'color0', 'outindex': 0}) self.colordef1 = OBColorDefinition( self.colorid1, {'txhash': 'color1', 'outindex': 0}) self.colordef2 = OBColorDefinition( self.colorid2, {'txhash': 'color2', 'outindex': 0}) self.asset_config = { 'monikers': ['blue'], 'color_set': [self.colordesc0], } self.basset_config = { 'monikers': ['bitcoin'], 'color_set': [''], } self.asset = AssetDefinition(self.colormap, self.asset_config) self.basset = AssetDefinition(self.colormap, self.basset_config) self.basic = BasicTxSpec(self.model) self.bbasic = BasicTxSpec(self.model) wam = self.model.get_address_manager() self.address0 = wam.get_new_address(self.asset.get_color_set()) self.addr0 = self.address0.get_address() self.bcolorset = ColorSet(self.colormap, ['']) self.baddress = wam.get_new_address(self.bcolorset) self.baddr = self.baddress.get_address() self.assetvalue0 = AdditiveAssetValue(asset=self.asset, value=5) self.assetvalue1 = AdditiveAssetValue(asset=self.asset, value=6) self.assetvalue2 = AdditiveAssetValue(asset=self.asset, value=7) self.bassetvalue = AdditiveAssetValue(asset=self.basset, value=8) self.assettarget0 = AssetTarget(self.addr0, self.assetvalue0) self.assettarget1 = AssetTarget(self.addr0, self.assetvalue1) self.assettarget2 = AssetTarget(self.addr0, self.assetvalue2) self.bassettarget = AssetTarget(self.baddr, self.bassetvalue) self.atargets = [self.assettarget0, self.assettarget1, self.assettarget2] # add some targets self.colorvalue0 = SimpleColorValue(colordef=self.colordef0, value=5) self.colortarget0 = ColorTarget(self.addr0, self.colorvalue0) self.colorvalue1 = SimpleColorValue(colordef=self.colordef0, value=6) self.colortarget1 = ColorTarget(self.addr0, self.colorvalue1) self.colorvalue2 = SimpleColorValue(colordef=self.colordef0, value=7) self.colortarget2 = ColorTarget(self.addr0, self.colorvalue2) self.bcolorvalue = SimpleColorValue(colordef=UNCOLORED_MARKER, value=8) self.bcolortarget = ColorTarget(self.baddr, self.bcolorvalue) self.targets = [self.colortarget0, self.colortarget1, self.colortarget2] self.transformer = TransactionSpecTransformer(self.model, self.config) self.blockhash = '00000000c927c5d0ee1ca362f912f83c462f644e695337ce3731b9f7c5d1ca8c' self.txhash = '4fe45a5ba31bab1e244114c4555d9070044c73c98636231c77657022d76b87f7' def test_basic(self): self.assertRaises(InvalidTargetError, self.basic.is_monocolor) self.assertRaises(InvalidTargetError, self.basic.add_target, self.colortarget0) self.basic.add_target(self.assettarget0) self.basic.add_target(self.assettarget1) self.basic.add_target(self.assettarget2) self.assertEqual(self.basic.is_monocolor(), True) self.assertEqual(self.basic.is_monoasset(), True) self.assertEqual(self.basic.targets, self.atargets) self.basic.add_target(self.bassettarget) self.assertEqual(self.basic.is_monoasset(), False) self.assertEqual(self.basic.is_monocolor(), False) self.assertRaises(InvalidTransformationError, self.basic.make_operational_tx_spec, self.asset) def add_coins(self): script = tools.compile( "OP_DUP OP_HASH160 {0} OP_EQUALVERIFY OP_CHECKSIG".format( self.address0.rawPubkey().encode("hex"))).encode("hex") self.model.utxo_man.store.add_utxo(self.addr0, self.txhash, 0, 100, script) script = tools.compile( "OP_DUP OP_HASH160 {0} OP_EQUALVERIFY OP_CHECKSIG".format( self.baddress.rawPubkey().encode("hex"))).encode("hex") self.model.utxo_man.store.add_utxo(self.baddr, self.txhash, 1, 20000, script) self.model.ccc.metastore.set_as_scanned(self.colorid0, self.blockhash) self.model.ccc.cdstore.add(self.colorid0, self.txhash, 0, 100, '') def test_operational(self): self.basic.add_target(self.assettarget0) self.basic.add_target(self.assettarget1) self.basic.add_target(self.assettarget2) op = self.transformer.transform_basic(self.basic, 'operational') self.assertTrue(self.transformer.classify_tx_spec(op), 'operational') self.assertRaises(InvalidTargetError, op.add_target, 1) self.assertEqual(ColorTarget.sum(op.get_targets()), ColorTarget.sum(self.targets)) self.assertEqual(op.get_change_addr(self.colordef0), self.addr0) self.assertEqual(op.get_change_addr(UNCOLORED_MARKER), self.baddr) self.assertEqual(op.get_required_fee(1).get_value(), 10000) self.assertRaises(InvalidColorIdError, op.get_change_addr, self.colordef1) cv = SimpleColorValue(colordef=self.colordef0, value=0) self.assertRaises(ZeroSelectError, op.select_coins, cv) cv = SimpleColorValue(colordef=self.colordef0, value=5) self.assertRaises(InsufficientFundsError, op.select_coins, cv) self.add_coins() self.assertEqual(op.select_coins(cv)[1].get_value(), 100) def test_composed(self): self.basic.add_target(self.assettarget0) self.basic.add_target(self.assettarget1) self.basic.add_target(self.assettarget2) self.add_coins() op = self.transformer.transform(self.basic, 'operational') self.assertEqual(op.get_change_addr(self.colordef0), self.addr0) self.assertEqual(op.get_change_addr(UNCOLORED_MARKER), self.baddr) comp = self.transformer.transform(op, 'composed') self.assertTrue(self.transformer.classify_tx_spec(comp), 'composed') signed = self.transformer.transform(comp, 'signed') self.assertTrue(self.transformer.classify_tx_spec(signed), 'signed') self.assertEqual(len(signed.get_hex_txhash()), 64) txdata = signed.get_tx_data() same = RawTxSpec.from_tx_data(self.model, txdata) self.assertEqual(same.get_hex_tx_data(), signed.get_hex_tx_data()) self.assertRaises(InvalidTransformationError, self.transformer.transform, signed, '') def test_other(self): self.assertEqual(self.transformer.classify_tx_spec(1), None) self.assertRaises(InvalidTransformationError, self.transformer.transform_basic, self.basic, '') self.assertRaises(InvalidTransformationError, self.transformer.transform_operational, self.basic, '') self.assertRaises(InvalidTransformationError, self.transformer.transform_composed, self.basic, '') self.assertRaises(InvalidTransformationError, self.transformer.transform_signed, self.basic, '') self.assertRaises(InvalidTransformationError, self.transformer.transform, '', '') self.add_coins() self.bbasic.add_target(self.bassettarget) signed = self.transformer.transform(self.bbasic, 'signed') self.assertEqual(len(signed.get_hex_txhash()), 64)
class Ngccc(apigen.Definition): """Next-Generation Colored Coin Client interface.""" def __init__(self, wallet=None, testnet=False): # sanitize inputs testnet = sanitize.flag(testnet) if not wallet: wallet = "%s.wallet" % ("testnet" if testnet else "mainnet") self.wallet = PersistentWallet(wallet, testnet) self.model_is_initialized = False def __getattribute__(self, name): if name in ['controller', 'model']: if not self.model_is_initialized: self.wallet.init_model() self.model = self.wallet.get_model() self.controller = WalletController(self.model) slef.model_is_initialized = True return object.__getattribute__(self, name) @apigen.command() def setconfigval(self, key, value): # FIXME behaviour ok? """Sets a value in the configuration. Key is expressed as: key.subkey.subsubkey """ # sanitize inputs key = sanitize.cfgkey(key) value = sanitize.cfgvalue(value) kpath = key.split('.') value = json.loads(value) # traverse the path until we get to the value we need to set if len(kpath) > 1: branch = self.wallet.wallet_config[kpath[0]] cdict = branch for k in kpath[1:-1]: cdict = cdict[k] cdict[kpath[-1]] = value value = branch if kpath[0] in self.wallet.wallet_config: self.wallet.wallet_config[kpath[0]] = value else: raise KeyNotFound(key) @apigen.command() def getconfigval(self, key): """Returns the value for a given key in the config. Key is expressed as: key.subkey.subsubkey """ # sanitize inputs key = sanitize.cfgkey(key) if not key: raise KeyNotFound(key) keys = key.split('.') config = self.wallet.wallet_config # traverse the path until we get the value for key in keys: config = config[key] return _print(config) @apigen.command() def dumpconfig(self): """Returns a dump of the current configuration.""" dict_config = dict(self.wallet.wallet_config.iteritems()) return _print(dict_config) @apigen.command() def importconfig(self, path): # FIXME what about subkeys and removed keys? """Import JSON config.""" with open(path, 'r') as fp: config = json.loads(fp.read()) wallet_config = self.wallet.wallet_config for k in config: wallet_config[k] = config[k] @apigen.command() def issueasset(self, moniker, quantity, unit="100000000", scheme="epobc"): """ Issue <quantity> of asset with name <moniker> and <unit> atoms, based on <scheme (epobc|obc)>.""" # sanitize inputs moniker = sanitize.moniker(moniker) quantity = sanitize.quantity(quantity) unit = sanitize.unit(unit) scheme = sanitize.scheme(scheme) self.controller.issue_coins(moniker, scheme, quantity, unit) return self.getasset(moniker) @apigen.command() def addassetjson(self, data): """Add a json asset definition. Enables the use of colors/assets issued by others. """ # sanitize inputs data = sanitize.jsonasset(data) self.controller.add_asset_definition(data) return self.getasset(data['monikers'][0]) @apigen.command() def addasset(self, moniker, color_description, unit=100000000): """Add a asset definition. Enables the use of colors/assets issued by others. """ # sanitize inputs moniker = sanitize.moniker(moniker) color_description = sanitize.colordesc(color_description) unit = sanitize.unit(unit) self.controller.add_asset_definition({ "monikers": [moniker], "color_set": [color_description], "unit" : unit }) return self.getasset(moniker) @apigen.command() def getasset(self, moniker): """Get the asset associated with the moniker.""" return _print(sanitize.asset(self.model, moniker).get_data()) @apigen.command() def listassets(self): """Lists all assets/colors registered.""" assets = self.controller.get_all_assets() return _print(map(lambda asset: asset.get_data(), assets)) def _getbalance(self, asset, unconfirmed, available): if unconfirmed: balance = self.controller.get_unconfirmed_balance(asset) elif available: balance = self.controller.get_available_balance(asset) else: balance = self.controller.get_total_balance(asset) return (asset.get_monikers()[0], asset.format_value(balance)) @apigen.command() def getbalance(self, moniker, unconfirmed=False, available=False): """Returns the balance for a particular asset.""" # sanitize inputs asset = sanitize.asset(self.model, moniker) unconfirmed = sanitize.flag(unconfirmed) available = sanitize.flag(available) balance = dict([self._getbalance(asset, unconfirmed, available)]) return _print(balance) @apigen.command() def getbalances(self, unconfirmed=False, available=False): """Returns the balances for all assets/colors.""" # sanitize inputs unconfirmed = sanitize.flag(unconfirmed) available = sanitize.flag(available) assets = self.controller.get_all_assets() func = lambda asset: self._getbalance(asset, unconfirmed, available) balances = dict(map(func, assets)) return _print(balances) @apigen.command() def newaddress(self, moniker): """Creates a new coloraddress for a given asset.""" # sanitize inputs asset = sanitize.asset(self.model, moniker) addressrecord = self.controller.get_new_address(asset) coloraddress = addressrecord.get_color_address() return _print(coloraddress) @apigen.command() def listaddresses(self, moniker): """Lists all addresses for a given asset""" # sanitize inputs asset = sanitize.asset(self.model, moniker) addressrecords = self.controller.get_all_addresses(asset) return _print([ao.get_color_address() for ao in addressrecords]) @apigen.command() def send(self, moniker, coloraddress, amount): """Send <coloraddress> given <amount> of an asset.""" # sanitize inputs asset = sanitize.asset(self.model, moniker) coloraddress = sanitize.coloraddress(self.model, asset, coloraddress) amount = sanitize.assetamount(asset, amount) txid = self.controller.send_coins(asset, [coloraddress], [amount]) return _print(txid) @apigen.command() def sendmanyjson(self, data): """Send amounts given in json fromatted data. Format [{'moniker':"val",'amount':"val",'coloraddress':"val"}] All entries must use the same color scheme. """ # sanitize inputs sendmany_entries = sanitize.sendmanyjson(self.model, data) return _print(self.controller.sendmany_coins(sendmany_entries)) @apigen.command() def sendmanycsv(self, path): """Send amounts in csv file with format 'moniker,coloraddress,amount'. All entries must use the same color scheme. """ # sanitize inputs sendmany_entries = sanitize.sendmanycsv(self.model, path) return _print(self.controller.sendmany_coins(sendmany_entries)) @apigen.command() def scan(self): """Update the database of transactions.""" sleep(5) self.controller.scan_utxos() @apigen.command() def fullrescan(self): """Rebuild database of wallet transactions.""" self.controller.full_rescan() @apigen.command() def history(self, moniker): """Show the history of transactions for given asset.""" # sanitize inputs asset = sanitize.asset(self.model, moniker) return _print(self.controller.get_history(asset)) @apigen.command() def received(self, moniker): """Returns total received amount for each coloraddress of a given asset. """ # sanitize inputs asset = sanitize.asset(self.model, moniker) received = {} def reformat(data): coloraddress = data['color_address'] colorvalue = data['value'].get_value() return (coloraddress, asset.format_value(colorvalue)) data = self.controller.get_received_by_address(asset) return _print(dict(map(reformat, data))) @apigen.command() def coinlog(self): """Returns the coin transaction log for this wallet.""" log = defaultdict(list) for coin in self.controller.get_coinlog(): moniker = coin.asset.get_monikers()[0] moniker = 'bitcoin' if moniker == '' else moniker log[moniker].append({ 'address' : coin.get_address(), 'txid' : coin.txhash, 'out' : coin.outindex, 'colorvalue' : coin.colorvalues[0].get_value(), 'value' : coin.value, 'confirmed' : coin.is_confirmed(), 'spendingtxs' : coin.get_spending_txs(), }) return _print(log) @apigen.command() def dumpprivkey(self, moniker, coloraddress): """Private key for a given coloraddress.""" # sanitize inputs asset = sanitize.asset(self.model, moniker) coloraddress = sanitize.coloraddress(self.model, asset, coloraddress) wam = self.model.get_address_manager() for addressrecord in wam.get_all_addresses(): if coloraddress == addressrecord.get_color_address(): return _print(addressrecord.get_private_key()) raise AddressNotFound(coloraddress) @apigen.command() def dumpprivkeys(self, moniker): """Lists all private keys for a given asset.""" # sanitize inputs asset = sanitize.asset(self.model, moniker) addressrecords = self.controller.get_all_addresses(asset) return _print(map(lambda ar: ar.get_private_key(), addressrecords)) def _init_p2ptrade(self): ewctrl = EWalletController(self.model, self.controller) config = {"offer_expiry_interval": 30, "ep_expiry_interval": 30} comm = HTTPComm(config, 'http://p2ptrade.btx.udoidio.info/messages') return EAgent(ewctrl, config, comm) def _p2ptrade_make_offer(self, we_sell, moniker, value, price, wait): # sanitize inputs asset = sanitize.asset(self.model, moniker) bitcoin = sanitize.asset(self.model, 'bitcoin') value = sanitize.assetamount(asset, value) price = sanitize.assetamount(bitcoin, price) wait = sanitize.integer(wait) total = int(Decimal(value)/Decimal(asset.unit)*Decimal(price)) color_desc = asset.get_color_set().color_desc_list[0] sell_side = {"color_spec": color_desc, "value": value} buy_side = {"color_spec": "", "value": total} agent = self._init_p2ptrade() if we_sell: agent.register_my_offer(MyEOffer(None, sell_side, buy_side)) else: agent.register_my_offer(MyEOffer(None, buy_side, sell_side)) self._p2ptrade_wait(agent, wait) def _p2ptrade_wait(self, agent, wait): if wait and wait > 0: for _ in xrange(wait): agent.update() sleep(1) else: for _ in xrange(4*6): agent.update() sleep(0.25) @apigen.command() def p2porders(self, moniker="", sellonly=False, buyonly=False): """Show peer to peer trade orders""" # sanitize inputs sellonly = sanitize.flag(sellonly) buyonly = sanitize.flag(buyonly) asset = None if moniker and moniker != 'bitcoin': asset = sanitize.asset(self.model, moniker) # get offers agent = self._init_p2ptrade() agent.update() offers = agent.their_offers.values() offers = map(lambda offer: offer.get_data(), offers) # filter asset if given if asset: descs = asset.get_color_set().color_desc_list def func(offer): return (offer["A"]["color_spec"] in descs or offer["B"]["color_spec"] in descs) offers = filter(func, offers) # filter sellonly if given if sellonly: offers = filter(lambda o: o["A"]["color_spec"] != "", offers) # filter buyonly if given if buyonly: offers = filter(lambda o: o["A"]["color_spec"] == "", offers) return _print(offers) @apigen.command() def p2psell(self, moniker, assetamount, btcprice, wait=30): """Sell <assetamount> for <btcprice> via peer to peer trade.""" self._p2ptrade_make_offer(True, moniker, assetamount, btcprice, wait) @apigen.command() def p2pbuy(self, moniker, assetamount, btcprice, wait=30): """Buy <assetamount> for <btcprice> via peer to peer trade.""" self._p2ptrade_make_offer(False, moniker, assetamount, btcprice, wait)
class Wallet(QtCore.QObject): balanceUpdated = QtCore.pyqtSignal(name='balanceUpdated') def __init__(self, dataDir, isTestNet): QtCore.QObject.__init__(self) self.lock = threading.Lock() self._patching_BaseTxDb() self.wallet_path = os.path.join(dataDir, 'wallet.sqlite') self._pwallet = PersistentWallet(self.wallet_path, isTestNet) self._set_wallet_settings(dataDir, isTestNet) self._pwallet.init_model() self._wallet = self._pwallet.get_model() self._controller = WalletController(self._wallet) self._utxo_fetcher = AsyncUTXOFetcher( self._wallet, self._pwallet.wallet_config.get('utxo_fetcher', {})) self._utxo_fetcher_timer = QtCore.QTimer() self._utxo_fetcher_timer.timeout.connect(self._utxo_fetcher.update) self._utxo_fetcher_timer.setInterval(1000) asset = self.get_asset_definition('bitcoin') if len(self._controller.get_all_addresses(asset)) == 0: self._controller.get_new_address(asset) self._create_club_asset() def _patching_BaseTxDb(self): original_add_tx = BaseTxDb.add_tx def new_add_tx(baseTxDb, txhash, txdata, raw_tx, *args, **kwargs): retval = original_add_tx(baseTxDb, txhash, txdata, raw_tx, *args, **kwargs) if retval: ctxs = raw_tx.composed_tx_spec coinStore = self._wallet.get_coin_manager().store all_addresses = [ a.get_address() for a in self._wallet.get_address_manager().get_all_addresses() ] lookup_moniker_by_address = {} for asset in self._controller.get_all_assets(): monikers = asset.get_monikers() for address in self._controller.get_all_addresses(asset): lookup_moniker_by_address[ address.get_address()] = monikers # txin for txin in ctxs.txins: prev_txhash, prev_outindex = txin.get_outpoint() coin_id = coinStore.find_coin(prev_txhash, prev_outindex) if coin_id: address = coinStore.get_coin(coin_id)['address'] self.balanceUpdated.emit() # txout for txout in ctxs.txouts: target_addr = txout.target_addr if target_addr in all_addresses: self.balanceUpdated.emit() return retval BaseTxDb.add_tx = new_add_tx def _set_wallet_settings(self, dataDir, isTestNet): self._pwallet.wallet_config['testnet'] = isTestNet ccc = self._pwallet.wallet_config.get('ccc', {}) ccc['colordb_path'] = os.path.join(dataDir, 'color_db.sqlite') self._pwallet.wallet_config['ccc'] = ccc def _create_club_asset(self): for asset in self._wallet.get_asset_definition_manager( ).get_all_assets(): for color in asset.get_color_set().get_data(): if color in clubAsset['color_set']: return self._wallet.get_asset_definition_manager().add_asset_definition( clubAsset) asset = self.get_asset_definition(clubAsset['monikers'][0]) if len(self._controller.get_all_addresses(asset)) == 0: self._controller.get_new_address(asset).get_color_address() def sync_start(self): self._utxo_fetcher.start_thread() self._utxo_fetcher_timer.start() def sync_stop(self): self._utxo_fetcher.stop() self._utxo_fetcher_timer.stop() def get_asset_definition(self, moniker): if isinstance(moniker, AssetDefinition): return moniker adm = self._wallet.get_asset_definition_manager() asset = adm.get_asset_by_moniker(moniker) if not asset: raise Exception("asset not found") return asset def get_address(self, moniker): asset = self.get_asset_definition(moniker) return self._controller.get_all_addresses(asset)[0].get_color_address() def get_bitcoin_address(self, moniker): asset = self.get_asset_definition(moniker) return self._controller.get_all_addresses(asset)[0].get_address() def get_total_balance(self, moniker): asset = self.get_asset_definition(moniker) return self._controller.get_total_balance(asset) def get_available_balance(self, moniker): asset = self.get_asset_definition(moniker) return self._controller.get_available_balance(asset) def get_unconfirmed_balance(self, moniker): asset = self.get_asset_definition(moniker) return self._controller.get_unconfirmed_balance(asset) def send_coins(self, moniker, address): asset = self.get_asset_definition(moniker) total = self.get_total_balance(asset) self._controller.send_coins(asset, [address], [total]) def get_auth_data(self, moniker): with self.lock: coin = self._wallet.make_coin_query({ 'asset': self.get_asset_definition(moniker), 'spent': False, }).get_result()[0] pubKey = public_pair_to_sec(coin.address_rec.publicPoint.pair(), compressed=False) return { 'color_set': clubAsset['color_set'][0], 'txhash': coin.txhash, 'outindex': coin.outindex, 'pubkey': pubKey.encode('hex'), 'privkey': coin.address_rec.rawPrivKey, 'address_rec': coin.address_rec, } def sign_data(self, data, privKey): with self.lock: symbols_set = string.ascii_letters + string.digits salt = ''.join([random.choice(symbols_set) for _ in xrange(20)]) data = int((hash160(str(data) + salt)).encode('hex'), 16) return { 'salt': salt, 'sign': ecdsa.sign(ecdsa.generator_secp256k1, privKey, data), } def validate_bitcoin_address(self, address): bcbytes = a2b_base58(str(address)) return bcbytes[-4:] == sha256(sha256( bcbytes[:-4]).digest()).digest()[:4]
class TestEWalletController(unittest.TestCase): def setUp(self): self.path = ":memory:" self.config = { 'hdw_master_key': '91813223e97697c42f05e54b3a85bae601f04526c5c053ff0811747db77cfdf5f1accb50b3765377c379379cd5aa512c38bf24a57e4173ef592305d16314a0f4', 'testnet': True, 'ccc': {'colordb_path' : self.path}, } self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() self.wc = WalletController(self.model) self.ewc = EWalletController(self.model, self.wc) self.bcolorset =self.ewc.resolve_color_spec('') self.cspec = "obc:03524a4d6492e8d43cb6f3906a99be5a1bcd93916241f759812828b301f25a6c:0:153267" def add_coins(self): self.config['asset_definitions'] = [ {"color_set": [""], "monikers": ["bitcoin"], "unit": 100000000}, {"color_set": [self.cspec], "monikers": ['test'], "unit": 1},] self.config['hdwam'] = { "genesis_color_sets": [ [self.cspec], ], "color_set_states": [ {"color_set": [""], "max_index": 1}, {"color_set": [self.cspec], "max_index": 7}, ] } self.config['bip0032'] = True self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() self.ewc.model = self.model self.wc.model = self.model # modify model colored coin context, so test runs faster ccc = self.model.ccc cdbuilder = ColorDataBuilderManager( ccc.colormap, ccc.blockchain_state, ccc.cdstore, ccc.metastore, AidedColorDataBuilder) ccc.colordata = ThinColorData( cdbuilder, ccc.blockchain_state, ccc.cdstore, ccc.colormap) # need to query the blockchain self.model.utxo_man.update_all() adm = self.model.get_asset_definition_manager() asset = adm.get_asset_by_moniker('test') cq = self.model.make_coin_query({"asset": asset}) utxo_list = cq.get_result() def test_resolve_color_spec(self): self.assertRaises(InvalidColorIdError, self.ewc.resolve_color_spec, 'nonexistent') self.assertTrue(isinstance(self.bcolorset, ColorSet)) self.assertEqual(self.bcolorset.color_id_set, set([0])) def test_select_inputs(self): cv = SimpleColorValue(colordef=UNCOLORED_MARKER, value=1) self.assertRaises(InsufficientFundsError, self.ewc.select_inputs, cv) def test_tx_spec(self): self.add_colors() our = SimpleColorValue(colordef=UNCOLORED_MARKER, value=500) colormap = self.model.get_color_map() colordef = colormap.get_color_def(self.cspec) their = SimpleColorValue(colordef=colordef, value=10) etx = self.ewc.make_etx_spec(our, their) self.assertTrue(isinstance(etx, ETxSpec)) for target in etx.targets: self.assertTrue(isinstance(target, ColorTarget)) signed = self.ewc.make_reply_tx(etx, our, their) self.assertTrue(isinstance(signed, RawTxSpec)) self.ewc.publish_tx(signed) etx = self.ewc.make_etx_spec(their, our) self.assertTrue(isinstance(etx, ETxSpec)) for target in etx.targets: self.assertTrue(isinstance(target, ColorTarget)) signed = self.ewc.make_reply_tx(etx, their, our) self.assertTrue(isinstance(signed, RawTxSpec)) oets = OperationalETxSpec(self.model, self.ewc) zero = SimpleColorValue(colordef=UNCOLORED_MARKER, value=0) self.assertRaises(ZeroSelectError, oets.select_coins, zero) toomuch = SimpleColorValue(colordef=UNCOLORED_MARKER, value=10000000000000) self.assertRaises(InsufficientFundsError, oets.select_coins, toomuch)
class TestEWalletController(unittest.TestCase): def setUp(self): self.pwallet = PersistentWallet(None, True) self.pwallet.init_model() self.model = self.pwallet.get_model() adm = self.model.get_asset_definition_manager() # make sure you have the asset 'testobc' in your testnet.wallet !! self.asset = adm.get_asset_by_moniker('testobc') self.color_spec = self.asset.get_color_set().get_data()[0] self.wc = WalletController(self.model) self.ewc = EWalletController(self.model, self.wc) def null(a): pass self.wc.publish_tx = null def test_resolve_color_spec(self): self.cd =self.ewc.resolve_color_spec('') self.assertRaises(KeyError, self.ewc.resolve_color_spec, 'nonexistent') self.assertTrue(isinstance(self.cd, ColorDefinition)) self.assertEqual(self.cd.get_color_id(), 0) def test_select_inputs(self): cv = SimpleColorValue(colordef=UNCOLORED_MARKER, value=10000000000000) self.assertRaises(InsufficientFundsError, self.ewc.select_inputs, cv) def test_tx_spec(self): alice_cv = { 'color_spec' : self.color_spec, 'value' : 10 } bob_cv = { 'color_spec' : "", 'value' : 500 } alice_offer = MyEOffer(None, alice_cv, bob_cv) bob_offer = MyEOffer(None, bob_cv, alice_cv) bob_etx = self.ewc.make_etx_spec(bob_cv, alice_cv) self.assertTrue(isinstance(bob_etx, ETxSpec)) for target in bob_etx.targets: # check address address = target[0] self.assertTrue(isinstance(address, type(u"unicode"))) # TODO check address is correct format # check color_spec color_spec = target[1] self.assertTrue(isinstance(color_spec, type("str"))) color_spec_parts = len(color_spec.split(":")) self.assertTrue(color_spec_parts == 4 or color_spec_parts == 1) # check value value = target[2] self.assertTrue(isinstance(value, type(10))) signed = self.ewc.make_reply_tx(bob_etx, alice_cv, bob_cv) self.assertTrue(isinstance(signed, RawTxSpec)) self.ewc.publish_tx(signed, alice_offer) alice_etx = self.ewc.make_etx_spec(alice_cv, bob_cv) self.assertTrue(isinstance(alice_etx, ETxSpec)) for target in alice_etx.targets: # check address address = target[0] self.assertTrue(isinstance(address, type(u"unicode"))) # TODO check address is correct format # check color_spec color_spec = target[1] self.assertTrue(isinstance(color_spec, type("str"))) color_spec_parts = len(color_spec.split(":")) self.assertTrue(color_spec_parts == 4 or color_spec_parts == 1) # check value value = target[2] self.assertTrue(isinstance(value, type(10))) signed = self.ewc.make_reply_tx(alice_etx, bob_cv, alice_cv) self.assertTrue(isinstance(signed, RawTxSpec)) oets = OperationalETxSpec(self.model, self.ewc) oets.set_our_value_limit(bob_cv) oets.prepare_inputs(alice_etx) zero = SimpleColorValue(colordef=UNCOLORED_MARKER, value=0) self.assertRaises(ZeroSelectError, oets.select_coins, zero) toomuch = SimpleColorValue(colordef=UNCOLORED_MARKER, value=10000000000000) self.assertRaises(InsufficientFundsError, oets.select_coins, toomuch)
def setUp(self): self.path = ":memory:" self.pwallet = PersistentWallet(self.path) self.config = {'dw_master_key': 'test', 'testnet': True, 'ccc': { 'colordb_path' : self.path}, 'bip0032': False } self.pwallet.wallet_config = self.config self.pwallet.init_model() self.model = self.pwallet.get_model() self.colormap = self.model.get_color_map() self.colordesc0 = "obc:color0:0:0" self.colordesc1 = "obc:color1:0:0" self.colordesc2 = "obc:color2:0:0" # add some colordescs self.colorid0 = self.colormap.resolve_color_desc(self.colordesc0) self.colorid1 = self.colormap.resolve_color_desc(self.colordesc1) self.colorid2 = self.colormap.resolve_color_desc(self.colordesc2) self.colordef0 = OBColorDefinition( self.colorid0, {'txhash': 'color0', 'outindex': 0}) self.colordef1 = OBColorDefinition( self.colorid1, {'txhash': 'color1', 'outindex': 0}) self.colordef2 = OBColorDefinition( self.colorid2, {'txhash': 'color2', 'outindex': 0}) self.asset_config = { 'monikers': ['blue'], 'color_set': [self.colordesc0], } self.basset_config = { 'monikers': ['bitcoin'], 'color_set': [''], } self.asset = AssetDefinition(self.colormap, self.asset_config) self.basset = AssetDefinition(self.colormap, self.basset_config) self.basic = BasicTxSpec(self.model) self.bbasic = BasicTxSpec(self.model) wam = self.model.get_address_manager() self.address0 = wam.get_new_address(self.asset.get_color_set()) self.addr0 = self.address0.get_address() self.bcolorset = ColorSet(self.colormap, ['']) self.baddress = wam.get_new_address(self.bcolorset) self.baddr = self.baddress.get_address() self.assetvalue0 = AdditiveAssetValue(asset=self.asset, value=5) self.assetvalue1 = AdditiveAssetValue(asset=self.asset, value=6) self.assetvalue2 = AdditiveAssetValue(asset=self.asset, value=7) self.bassetvalue = AdditiveAssetValue(asset=self.basset, value=8) self.assettarget0 = AssetTarget(self.addr0, self.assetvalue0) self.assettarget1 = AssetTarget(self.addr0, self.assetvalue1) self.assettarget2 = AssetTarget(self.addr0, self.assetvalue2) self.bassettarget = AssetTarget(self.baddr, self.bassetvalue) self.atargets = [self.assettarget0, self.assettarget1, self.assettarget2] # add some targets self.colorvalue0 = SimpleColorValue(colordef=self.colordef0, value=5) self.colortarget0 = ColorTarget(self.addr0, self.colorvalue0) self.colorvalue1 = SimpleColorValue(colordef=self.colordef0, value=6) self.colortarget1 = ColorTarget(self.addr0, self.colorvalue1) self.colorvalue2 = SimpleColorValue(colordef=self.colordef0, value=7) self.colortarget2 = ColorTarget(self.addr0, self.colorvalue2) self.bcolorvalue = SimpleColorValue(colordef=UNCOLORED_MARKER, value=8) self.bcolortarget = ColorTarget(self.baddr, self.bcolorvalue) self.targets = [self.colortarget0, self.colortarget1, self.colortarget2] self.transformer = TransactionSpecTransformer(self.model, self.config) self.blockhash = '00000000c927c5d0ee1ca362f912f83c462f644e695337ce3731b9f7c5d1ca8c' self.txhash = '4fe45a5ba31bab1e244114c4555d9070044c73c98636231c77657022d76b87f7'
def setUp(self): from ngcccbase.pwallet import PersistentWallet from ngcccbase.wallet_controller import WalletController self.pwallet = PersistentWallet(":memory:", True) self.pwallet.init_model() self.wctrl = WalletController(self.pwallet.wallet_model)
class TestWalletController(unittest.TestCase): def setUp(self): self.path = ":memory:" self.config = {"dw_master_key": "test", "testnet": True, "ccc": {"colordb_path": self.path}, "bip0032": False} self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() self.wc = WalletController(self.model) self.wc.testing = True self.wc.debug = True self.colormap = self.model.get_color_map() self.bcolorset = ColorSet(self.colormap, [""]) wam = self.model.get_address_manager() self.baddress = wam.get_new_address(self.bcolorset) self.baddr = self.baddress.get_address() self.blockhash = "00000000c927c5d0ee1ca362f912f83c462f644e695337ce3731b9f7c5d1ca8c" self.txhash = "4fe45a5ba31bab1e244114c4555d9070044c73c98636231c77657022d76b87f7" script = tools.compile( "OP_DUP OP_HASH160 {0} OP_EQUALVERIFY OP_CHECKSIG".format(self.baddress.rawPubkey().encode("hex")) ).encode("hex") self.model.utxo_man.store.add_utxo(self.baddr, self.txhash, 0, 100, script) script = tools.compile( "OP_DUP OP_HASH160 {0} OP_EQUALVERIFY OP_CHECKSIG".format(self.baddress.rawPubkey().encode("hex")) ).encode("hex") self.model.utxo_man.store.add_utxo(self.baddr, self.txhash, 1, 1000000000, script) self.model.ccc.blockchain_state.bitcoind = MockBitcoinD("test") def x(s): return self.blockhash, True self.model.ccc.blockchain_state.get_tx_blockhash = x self.moniker = "test" self.wc.issue_coins(self.moniker, "obc", 10000, 1) self.asset = self.model.get_asset_definition_manager().get_asset_by_moniker(self.moniker) self.basset = self.model.get_asset_definition_manager().get_asset_by_moniker("bitcoin") self.color_id = list(self.asset.color_set.color_id_set)[0] self.model.ccc.metastore.set_as_scanned(self.color_id, self.blockhash) def test_issue(self): self.assertRaises(InvalidColorDefinitionError, self.wc.issue_coins, self.moniker, "nonexistent", 10000, 1) item = self.wc.get_history(self.asset)[0] self.assertEqual(item["action"], "issued") self.assertEqual(item["value"], 10000) self.wc.scan_utxos() item = self.wc.get_history(self.asset)[0] self.assertEqual(item["action"], "issued") self.assertEqual(item["value"], 10000) def test_new_address(self): addr = self.wc.get_new_address(self.asset) addrs = self.wc.get_all_addresses(self.asset) self.assertEqual(len(addr.get_address()), 34) self.assertTrue(addr in addrs) for d in self.wc.get_address_balance(self.asset): if d["address"] == addr.get_address(): self.assertEqual(d["value"], 0) def test_get_all_assets(self): self.assertTrue(self.asset in self.wc.get_all_assets()) def test_get_balance(self): self.assertEqual(self.wc.get_total_balance(self.asset), 10000) def test_add_asset(self): moniker = "addtest" params = {"monikers": [moniker], "color_set": ["obc:aaaaaaaaaaaaaaaaa:0:0"], "unit": 1} self.wc.add_asset_definition(params) asset = self.model.get_asset_definition_manager().get_asset_by_moniker(moniker) self.assertEqual(self.wc.get_total_balance(asset), 0) self.assertEqual(self.wc.get_history(asset), []) def test_send(self): addr1 = self.wc.get_new_address(self.asset) addr2 = self.wc.get_new_address(self.asset) color_addrs = [addr1.get_color_address(), addr2.get_color_address()] self.wc.send_coins(self.asset, color_addrs, [1000, 2000]) self.assertRaises(AssetMismatchError, self.wc.send_coins, self.basset, color_addrs, [1000, 2000])
class TestAgent(unittest.TestCase): def setUp(self): self.pwallet = PersistentWallet(None, True) self.pwallet.init_model() self.model = self.pwallet.get_model() adm = self.model.get_asset_definition_manager() # make sure you have the asset 'testobc' in your testnet.wallet !! self.asset = adm.get_asset_by_moniker('testobc') self.color_spec = self.asset.get_color_set().get_data()[0] self.comm0 = MockComm() self.comm1 = MockComm() self.comm0.add_peer(self.comm1) self.comm1.add_peer(self.comm0) self.wc = WalletController(self.model) self.ewc = EWalletController(self.model, self.wc) self.econfig = {"offer_expiry_interval": 30, "ep_expiry_interval": 30} self.agent0 = EAgent(self.ewc, self.econfig, self.comm0) self.agent1 = EAgent(self.ewc, self.econfig, self.comm1) self.cv0 = { 'color_spec' : "", 'value' : 100 } self.cv1 = { 'color_spec' : self.color_spec, 'value' : 200 } self.offer0 = MyEOffer(None, self.cv0, self.cv1) self.offer1 = MyEOffer(None, self.cv1, self.cv0) def test_set_event_handler(self): tmp = { 'test': 0} def handler(val): tmp['test'] = val self.agent0.set_event_handler('click', handler) self.agent0.fire_event('click', 7) self.assertEqual(tmp['test'], 7) self.agent0.ep_timeout = time.time() - 100 self.assertFalse(self.agent0.has_active_ep()) def test_real(self): self.assertFalse(self.agent0.has_active_ep()) self.agent0.register_my_offer(self.offer0) self.agent1.register_my_offer(self.offer1) for i in range(3): self.agent0._update_state() self.agent1._update_state() self.assertFalse(self.agent0.has_active_ep()) self.assertFalse(self.agent1.has_active_ep()) m0 = self.comm0.get_messages() m1 = self.comm1.get_messages() self.assertEquals(len(m0), 2) self.assertEquals(len(m1), 2) self.assertEquals(self.offer0.get_data(), m0[1]['offer']) self.assertEquals(self.offer0.get_data(), m1[1]['offer']) # expire offers offer2 = MyEOffer(None, self.cv0, self.cv1) self.agent0.register_my_offer(offer2) self.agent0.update() self.agent0.update() self.agent1.update() self.agent0.cancel_my_offer(offer2) self.agent0.update() self.agent1.update() self.assertFalse(self.agent0.has_active_ep()) self.assertFalse(self.agent1.has_active_ep()) offer3 = MyEOffer(None, self.cv1, self.cv0) self.agent0.make_exchange_proposal(offer3, offer2) self.assertRaises(Exception, self.agent0.make_exchange_proposal, offer3, offer2) ep = MyEProposal(self.ewc, offer3, offer2) def raiseException(x): raise Exception() self.agent0.set_event_handler('accept_ep', raiseException) # methods that should do nothing now that we have an active ep self.agent0.accept_exchange_proposal(ep) self.agent0.match_offers() self.agent0.register_their_offer(offer3) self.agent0.accept_exchange_proposal(ep) ep2 = MyEProposal(self.ewc, offer3, offer2) self.agent0.dispatch_exchange_proposal(ep2.get_data()) # test a few corner cases self.agent0.register_my_offer(offer2) offer2.refresh(-1000) self.assertTrue(offer2.expired()) self.agent0.service_my_offers() self.agent0.cancel_my_offer(offer2) self.agent0.register_their_offer(offer3) offer3.refresh(-1000) self.agent0.service_their_offers()
class Wallet(QtCore.QObject): balanceUpdated = QtCore.pyqtSignal(name='balanceUpdated') def __init__(self, dataDir, isTestNet): QtCore.QObject.__init__(self) self.lock = threading.Lock() self._patching_BaseTxDb() self.wallet_path = os.path.join(dataDir, 'wallet.sqlite') self._pwallet = PersistentWallet(self.wallet_path, isTestNet) self._set_wallet_settings(dataDir, isTestNet) self._pwallet.init_model() self._wallet = self._pwallet.get_model() self._controller = WalletController(self._wallet) self._utxo_fetcher = AsyncUTXOFetcher( self._wallet, self._pwallet.wallet_config.get('utxo_fetcher', {})) self._utxo_fetcher_timer = QtCore.QTimer() self._utxo_fetcher_timer.timeout.connect(self._utxo_fetcher.update) self._utxo_fetcher_timer.setInterval(1000) asset = self.get_asset_definition('bitcoin') if len(self._controller.get_all_addresses(asset)) == 0: self._controller.get_new_address(asset) self._create_club_asset() def _patching_BaseTxDb(self): original_add_tx = BaseTxDb.add_tx def new_add_tx(baseTxDb, txhash, txdata, raw_tx, *args, **kwargs): retval = original_add_tx(baseTxDb, txhash, txdata, raw_tx, *args, **kwargs) if retval: ctxs = raw_tx.composed_tx_spec coinStore = self._wallet.get_coin_manager().store all_addresses = [a.get_address() for a in self._wallet.get_address_manager().get_all_addresses()] lookup_moniker_by_address = {} for asset in self._controller.get_all_assets(): monikers = asset.get_monikers() for address in self._controller.get_all_addresses(asset): lookup_moniker_by_address[address.get_address()] = monikers # txin for txin in ctxs.txins: prev_txhash, prev_outindex = txin.get_outpoint() coin_id = coinStore.find_coin(prev_txhash, prev_outindex) if coin_id: address = coinStore.get_coin(coin_id)['address'] self.balanceUpdated.emit() # txout for txout in ctxs.txouts: target_addr = txout.target_addr if target_addr in all_addresses: self.balanceUpdated.emit() return retval BaseTxDb.add_tx = new_add_tx def _set_wallet_settings(self, dataDir, isTestNet): self._pwallet.wallet_config['testnet'] = isTestNet ccc = self._pwallet.wallet_config.get('ccc', {}) ccc['colordb_path'] = os.path.join(dataDir, 'color_db.sqlite') self._pwallet.wallet_config['ccc'] = ccc def _create_club_asset(self): for asset in self._wallet.get_asset_definition_manager().get_all_assets(): for color in asset.get_color_set().get_data(): if color in clubAsset['color_set']: return self._wallet.get_asset_definition_manager().add_asset_definition(clubAsset) asset = self.get_asset_definition(clubAsset['monikers'][0]) if len(self._controller.get_all_addresses(asset)) == 0: self._controller.get_new_address(asset).get_color_address() def sync_start(self): self._utxo_fetcher.start_thread() self._utxo_fetcher_timer.start() def sync_stop(self): self._utxo_fetcher.stop() self._utxo_fetcher_timer.stop() def get_asset_definition(self, moniker): if isinstance(moniker, AssetDefinition): return moniker adm = self._wallet.get_asset_definition_manager() asset = adm.get_asset_by_moniker(moniker) if not asset: raise Exception("asset not found") return asset def get_address(self, moniker): asset = self.get_asset_definition(moniker) return self._controller.get_all_addresses(asset)[0].get_color_address() def get_bitcoin_address(self, moniker): asset = self.get_asset_definition(moniker) return self._controller.get_all_addresses(asset)[0].get_address() def get_total_balance(self, moniker): asset = self.get_asset_definition(moniker) return self._controller.get_total_balance(asset) def get_available_balance(self, moniker): asset = self.get_asset_definition(moniker) return self._controller.get_available_balance(asset) def get_unconfirmed_balance(self, moniker): asset = self.get_asset_definition(moniker) return self._controller.get_unconfirmed_balance(asset) def send_coins(self, moniker, address): asset = self.get_asset_definition(moniker) total = self.get_total_balance(asset) self._controller.send_coins(asset, [address], [total]) def get_auth_data(self, moniker): with self.lock: coin = self._wallet.make_coin_query({ 'asset': self.get_asset_definition(moniker), 'spent': False, }).get_result()[0] pubKey = public_pair_to_sec(coin.address_rec.publicPoint.pair(), compressed=False) return { 'color_set': clubAsset['color_set'][0], 'txhash': coin.txhash, 'outindex': coin.outindex, 'pubkey': pubKey.encode('hex'), 'privkey': coin.address_rec.rawPrivKey, 'address_rec': coin.address_rec, } def sign_data(self, data, privKey): with self.lock: symbols_set = string.ascii_letters + string.digits salt = ''.join([random.choice(symbols_set) for _ in xrange(20)]) data = int((hash160(str(data) + salt)).encode('hex'), 16) return { 'salt': salt, 'sign': ecdsa.sign(ecdsa.generator_secp256k1, privKey, data), } def validate_bitcoin_address(self, address): bcbytes = a2b_base58(str(address)) return bcbytes[-4:] == sha256(sha256(bcbytes[:-4]).digest()).digest()[:4]
class TestEWalletController(unittest.TestCase): def setUp(self): self.path = ":memory:" self.config = { 'hdw_master_key': '91813223e97697c42f05e54b3a85bae601f04526c5c053ff0811747db77cfdf5f1accb50b3765377c379379cd5aa512c38bf24a57e4173ef592305d16314a0f4', 'testnet': True, 'ccc': { 'colordb_path': self.path }, } self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() self.wc = WalletController(self.model) self.ewc = EWalletController(self.model, self.wc) self.bcolorset = self.ewc.resolve_color_spec('') self.cspec = "obc:03524a4d6492e8d43cb6f3906a99be5a1bcd93916241f759812828b301f25a6c:0:153267" def add_coins(self): self.config['asset_definitions'] = [ { "color_set": [""], "monikers": ["bitcoin"], "unit": 100000000 }, { "color_set": [self.cspec], "monikers": ['test'], "unit": 1 }, ] self.config['hdwam'] = { "genesis_color_sets": [ [self.cspec], ], "color_set_states": [ { "color_set": [""], "max_index": 1 }, { "color_set": [self.cspec], "max_index": 7 }, ] } self.config['bip0032'] = True self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() self.ewc.model = self.model self.wc.model = self.model # modify model colored coin context, so test runs faster ccc = self.model.ccc cdbuilder = ColorDataBuilderManager(ccc.colormap, ccc.blockchain_state, ccc.cdstore, ccc.metastore, AidedColorDataBuilder) ccc.colordata = ThinColorData(cdbuilder, ccc.blockchain_state, ccc.cdstore, ccc.colormap) # need to query the blockchain self.model.utxo_man.update_all() adm = self.model.get_asset_definition_manager() asset = adm.get_asset_by_moniker('test') cq = self.model.make_coin_query({"asset": asset}) utxo_list = cq.get_result() def test_resolve_color_spec(self): self.assertRaises(InvalidColorIdError, self.ewc.resolve_color_spec, 'nonexistent') self.assertTrue(isinstance(self.bcolorset, ColorSet)) self.assertEqual(self.bcolorset.color_id_set, set([0])) def test_select_inputs(self): cv = SimpleColorValue(colordef=UNCOLORED_MARKER, value=1) self.assertRaises(InsufficientFundsError, self.ewc.select_inputs, cv) def test_tx_spec(self): self.add_colors() our = SimpleColorValue(colordef=UNCOLORED_MARKER, value=500) colormap = self.model.get_color_map() colordef = colormap.get_color_def(self.cspec) their = SimpleColorValue(colordef=colordef, value=10) etx = self.ewc.make_etx_spec(our, their) self.assertTrue(isinstance(etx, ETxSpec)) for target in etx.targets: self.assertTrue(isinstance(target, ColorTarget)) signed = self.ewc.make_reply_tx(etx, our, their) self.assertTrue(isinstance(signed, RawTxSpec)) self.ewc.publish_tx(signed) etx = self.ewc.make_etx_spec(their, our) self.assertTrue(isinstance(etx, ETxSpec)) for target in etx.targets: self.assertTrue(isinstance(target, ColorTarget)) signed = self.ewc.make_reply_tx(etx, their, our) self.assertTrue(isinstance(signed, RawTxSpec)) oets = OperationalETxSpec(self.model, self.ewc) zero = SimpleColorValue(colordef=UNCOLORED_MARKER, value=0) self.assertRaises(ZeroSelectError, oets.select_coins, zero) toomuch = SimpleColorValue(colordef=UNCOLORED_MARKER, value=10000000000000) self.assertRaises(InsufficientFundsError, oets.select_coins, toomuch)
def add_coins(self): self.config['asset_definitions'] = [ { "color_set": [""], "monikers": ["bitcoin"], "unit": 100000000 }, { "color_set": [self.cspec], "monikers": ['test'], "unit": 1 }, ] self.config['hdwam'] = { "genesis_color_sets": [ [self.cspec], ], "color_set_states": [ { "color_set": [""], "max_index": 1 }, { "color_set": [self.cspec], "max_index": 7 }, ] } self.config['bip0032'] = True self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() self.ewc.model = self.model self.wc.model = self.model def null(a): pass self.wc.publish_tx = null # modify model colored coin context, so test runs faster ccc = self.model.ccc cdbuilder = ColorDataBuilderManager(ccc.colormap, ccc.blockchain_state, ccc.cdstore, ccc.metastore, AidedColorDataBuilder) ccc.colordata = ThinColorData(cdbuilder, ccc.blockchain_state, ccc.cdstore, ccc.colormap) # need to query the blockchain self.model.utxo_man.update_all() adm = self.model.get_asset_definition_manager() asset = adm.get_asset_by_moniker('test') cq = self.model.make_coin_query({"asset": asset}) utxo_list = cq.get_result() self.cd = ColorDefinition.from_color_desc(1, self.cspec) self.cv0 = SimpleColorValue(colordef=UNCOLORED_MARKER, value=100) self.cv1 = SimpleColorValue(colordef=self.cd, value=200) self.offer0 = MyEOffer(None, self.cv0, self.cv1) self.offer1 = MyEOffer(None, self.cv1, self.cv0)
class TestWalletController(unittest.TestCase): def setUp(self): self.path = ":memory:" self.config = { 'dw_master_key': 'test', 'testnet': True, 'ccc': { 'colordb_path': self.path }, 'bip0032': False } self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() self.wc = WalletController(self.model) self.wc.testing = True self.wc.debug = True self.colormap = self.model.get_color_map() self.bcolorset = ColorSet(self.colormap, ['']) wam = self.model.get_address_manager() self.baddress = wam.get_new_address(self.bcolorset) self.baddr = self.baddress.get_address() self.blockhash = '00000000c927c5d0ee1ca362f912f83c462f644e695337ce3731b9f7c5d1ca8c' self.txhash = '4fe45a5ba31bab1e244114c4555d9070044c73c98636231c77657022d76b87f7' script = tools.compile( "OP_DUP OP_HASH160 {0} OP_EQUALVERIFY OP_CHECKSIG".format( self.baddress.rawPubkey().encode("hex"))).encode("hex") self.model.utxo_man.store.add_utxo(self.baddr, self.txhash, 0, 100, script) script = tools.compile( "OP_DUP OP_HASH160 {0} OP_EQUALVERIFY OP_CHECKSIG".format( self.baddress.rawPubkey().encode("hex"))).encode("hex") self.model.utxo_man.store.add_utxo(self.baddr, self.txhash, 1, 1000000000, script) self.model.ccc.blockchain_state.bitcoind = MockBitcoinD('test') def x(s): return self.blockhash, True self.model.ccc.blockchain_state.get_tx_blockhash = x self.moniker = 'test' self.wc.issue_coins(self.moniker, 'obc', 10000, 1) self.asset = self.model.get_asset_definition_manager( ).get_asset_by_moniker(self.moniker) self.basset = self.model.get_asset_definition_manager( ).get_asset_by_moniker('bitcoin') self.color_id = list(self.asset.color_set.color_id_set)[0] self.model.ccc.metastore.set_as_scanned(self.color_id, self.blockhash) def test_issue(self): self.assertRaises(InvalidColorDefinitionError, self.wc.issue_coins, self.moniker, 'nonexistent', 10000, 1) item = self.wc.get_history(self.asset)[0] self.assertEqual(item['action'], 'issued') self.assertEqual(item['value'], 10000) self.wc.scan_utxos() item = self.wc.get_history(self.asset)[0] self.assertEqual(item['action'], 'issued') self.assertEqual(item['value'], 10000) def test_new_address(self): addr = self.wc.get_new_address(self.asset) addrs = self.wc.get_all_addresses(self.asset) self.assertEqual(len(addr.get_address()), 34) self.assertTrue(addr in addrs) for d in self.wc.get_received_by_address(self.asset): if d['address'] == addr.get_address(): self.assertEqual(d['value'], 0) def test_get_all_assets(self): self.assertTrue(self.asset in self.wc.get_all_assets()) def test_get_balance(self): self.assertEqual(self.wc.get_total_balance(self.asset), 10000) def test_add_asset(self): moniker = 'addtest' params = { "monikers": [moniker], "color_set": ['obc:aaaaaaaaaaaaaaaaa:0:0'], "unit": 1 } self.wc.add_asset_definition(params) asset = self.model.get_asset_definition_manager().get_asset_by_moniker( moniker) self.assertEqual(self.wc.get_total_balance(asset), 0) self.assertEqual(self.wc.get_history(asset), []) def test_send(self): addr1 = self.wc.get_new_address(self.asset) addr2 = self.wc.get_new_address(self.asset) color_addrs = [addr1.get_color_address(), addr2.get_color_address()] self.wc.send_coins(self.asset, color_addrs, [1000, 2000]) self.assertRaises(AssetMismatchError, self.wc.send_coins, self.basset, color_addrs, [1000, 2000])
class TestWalletModel(unittest.TestCase): def setUp(self): self.path = ":memory:" self.config = { 'hdw_master_key': '91813223e97697c42f05e54b3a85bae601f04526c5c053ff0811747db77cfdf5f1accb50b3765377c379379cd5aa512c38bf24a57e4173ef592305d16314a0f4', 'testnet': True, 'ccc': {'colordb_path' : self.path}, } self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() self.colormap = self.model.get_color_map() self.bcolorset = ColorSet(self.colormap, ['']) self.basset = self.model.get_asset_definition_manager( ).get_asset_by_moniker('bitcoin') self.cqf = self.model.get_coin_query_factory() def test_get_tx_db(self): self.assertTrue(isinstance(self.model.get_tx_db(), TxDb)) def test_is_testnet(self): self.assertTrue(self.model.is_testnet()) def test_get_coin_query_factory(self): self.assertTrue(isinstance(self.cqf, CoinQueryFactory)) self.cqf.make_query({'color_set': self.bcolorset}) self.cqf.make_query({'color_id_set': self.bcolorset.color_id_set}) self.cqf.make_query({'asset': self.basset}) self.assertRaises(Exception, self.cqf.make_query, {}) def test_transform(self): tx_spec = BasicTxSpec(self.model) self.assertRaises(InvalidTargetError, self.model.transform_tx_spec, tx_spec, 'signed') def test_make_query(self): q = self.model.make_coin_query({'color_set': self.bcolorset}) self.assertTrue(isinstance(q, UTXOQuery)) def test_get_address_manager(self): m = self.model.get_address_manager() self.assertTrue(issubclass(m.__class__, DWalletAddressManager)) def test_get_history(self): self.config['asset_definitions'] = [ {"color_set": [""], "monikers": ["bitcoin"], "unit": 100000000}, {"color_set": ["obc:03524a4d6492e8d43cb6f3906a99be5a1bcd93916241f759812828b301f25a6c:0:153267"], "monikers": ['test'], "unit": 1},] self.config['hdwam'] = { "genesis_color_sets": [ ["obc:03524a4d6492e8d43cb6f3906a99be5a1bcd93916241f759812828b301f25a6c:0:153267"], ], "color_set_states": [ {"color_set": [""], "max_index": 1}, {"color_set": ["obc:03524a4d6492e8d43cb6f3906a99be5a1bcd93916241f759812828b301f25a6c:0:153267"], "max_index": 7}, ] } self.config['bip0032'] = True self.pwallet = PersistentWallet(self.path, self.config) self.pwallet.init_model() self.model = self.pwallet.get_model() # modify model colored coin context, so test runs faster ccc = self.model.ccc cdbuilder = ColorDataBuilderManager( ccc.colormap, ccc.blockchain_state, ccc.cdstore, ccc.metastore, AidedColorDataBuilder) ccc.colordata = ThinColorData( cdbuilder, ccc.blockchain_state, ccc.cdstore, ccc.colormap) wc = WalletController(self.model) adm = self.model.get_asset_definition_manager() asset = adm.get_asset_by_moniker('test') self.model.utxo_man.update_all() cq = self.model.make_coin_query({"asset": asset}) utxo_list = cq.get_result() # send to the second address so the mempool has something addrs = wc.get_all_addresses(asset) wc.send_coins(asset, [addrs[1].get_color_address()], [1000]) history = self.model.get_history_for_asset(asset) self.assertTrue(len(history) > 30)