def listmyassets_filter_zeros(self): """Sometimes the asset cache will contain zero-quantity holdings for some assets (until they're flushed). These shouldn't be returned by listmyassets. """ # activate assets self.nodes[0].generate(500) self.sync_all() assert_equal(0, len(self.nodes[0].listmyassets())) assert_equal(0, len(self.nodes[1].listmyassets())) self.nodes[0].issue("FOO", 1000) self.nodes[0].generate(10) self.sync_all() result = self.nodes[0].listmyassets() assert_equal(2, len(result)) assert_contains_pair("FOO", 1000, result) assert_contains_pair("FOO!", 1, result) address_to = self.nodes[1].getnewaddress() self.nodes[0].transfer("FOO", 1000, address_to) self.nodes[0].generate(10) self.sync_all() result = self.nodes[0].listmyassets() assert_equal(1, len(result)) assert_contains_pair("FOO!", 1, result) result = self.nodes[1].listmyassets() assert_equal(1, len(result)) assert_contains_pair("FOO", 1000, result)
def reorg_test(self): height = int(self.options.height) peers = self.num_nodes tip_age = int(self.options.tip_age) should_reorg = int(self.options.should_reorg) self.log.info(f"Doing a reorg test with height: {height}, peers: {peers}, tip_age: {tip_age}. " + \ f"Should reorg? *{should_reorg}*") asset_name = "MOON_STONES" adversary = self.nodes[0] subject = self.nodes[-1] # enough to activate assets start = 432 self.log.info(f"Setting all node times to {tip_age} seconds ago...") now = int(round(time.time())) set_node_times(self.nodes, now - tip_age) self.log.info( f"Mining {start} starter blocks on all nodes and syncing...") subject.generate(round(start / 2)) self.sync_all() adversary.generate(round(start / 2)) self.sync_all() self.log.info("Stopping adversary node...") self.stop_node(0) self.log.info(f"Subject is issuing asset: {asset_name}...") subject.issue(asset_name) self.log.info(f"Miners are mining {height} blocks...") subject.generate(height) wait_until(lambda: [n.getblockcount() for n in self.nodes[1:]] == [height + start] * (peers - 1), err_msg="Wait for BlockCount") self.log.info("BlockCount: " + str([start] + [n.getblockcount() for n in self.nodes[1:]])) self.log.info("Restarting adversary node...") self.start_node(0) self.log.info(f"Adversary is issuing asset: {asset_name}...") adversary.issue(asset_name) self.log.info( f"Adversary is mining {height*2} (2 x {height}) blocks over the next ~{tip_age} seconds..." ) interval = round(tip_age / (height * 2)) + 1 for i in range(0, height * 2): set_node_times(self.nodes, (now - tip_age) + ((i + 1) * interval)) adversary.generate(1) assert (adversary.getblockcount() - start == (subject.getblockcount() - start) * 2) besttimes = [ n.getblock(n.getbestblockhash())['time'] for n in self.nodes ] self.log.info("BestTimes: " + str(besttimes)) self.log.info( f"Adversary: {besttimes[0]}; subject: {besttimes[-1]}; difference: {besttimes[0] - besttimes[-1]}; expected gte: {tip_age}" ) assert (besttimes[0] - besttimes[-1] >= tip_age) self.log.info("BlockCount: " + str([n.getblockcount() for n in self.nodes])) self.log.info("Reconnecting the network and syncing the chain...") for i in range(1, peers): connect_nodes_bi(self.nodes, 0, i, should_reorg) expected_height = start + height subject_owns_asset = True if should_reorg > 0: self.log.info( f"Expected a reorg -- blockcount should be {expected_height} and subject should own {asset_name} (waiting 5 seconds)..." ) expected_height += height subject_owns_asset = False else: self.log.info( f"Didn't expect a reorg -- blockcount should remain {expected_height} and both subject and adversary should own {asset_name} (waiting 5 seconds)..." ) # noinspection PyBroadException try: wait_until( lambda: [n.getblockcount() for n in self.nodes] == [expected_height] * peers, timeout=5, err_msg="getblockcount") except: pass self.log.info("BlockCount: " + str([n.getblockcount() for n in self.nodes])) assert_equal(subject.getblockcount(), expected_height) assert_contains_pair(asset_name + '!', 1, adversary.listmyassets()) if subject_owns_asset: assert_contains_pair(asset_name + '!', 1, subject.listmyassets()) else: assert_does_not_contain_key(asset_name + '!', subject.listmyassets())
def test_messaging(self): self.log.info("Testing messaging!") n0, n1 = self.nodes[0], self.nodes[1] spam_name = "SPAM" asset_name = "MESSAGING" owner_name = "MESSAGING!" channel_one = "MESSAGING~ONE" channel_two = "MESSAGING~TWO" ipfs_hash = "QmZPGfJojdTzaqCWJu2m3krark38X1rqEHBo4SjeqHKB26" # need ownership before channels can be created assert_raises_rpc_error(-32600, "Wallet doesn't have asset: " + owner_name, n0.issue, channel_one) n0.issue(asset_name, 100) n0.issue(channel_one) n0.issue(channel_two) n0.issue(spam_name, 100) n0.generate(1) self.sync_all() # you're auto-subscribed to your own channels n0_channels = n0.viewallmessagechannels() assert_contains(owner_name, n0_channels) assert_contains(channel_one, n0_channels) assert_contains(channel_two, n0_channels) # n1 subscribes to owner and channel one assert_equal([], n1.viewallmessagechannels()) n1.subscribetochannel(owner_name) n1.subscribetochannel(channel_one) n1_channels = n1.viewallmessagechannels() assert_contains(owner_name, n1_channels) assert_contains(channel_one, n1_channels) assert_does_not_contain(channel_two, n1_channels) # n0 sends a message on owner n0.sendmessage(owner_name, ipfs_hash) n0.generate(1) self.sync_all() # n1 views then clears messages n1_messages = n1.viewallmessages() assert_equal(1, len(n1_messages)) message = n1_messages[0] assert_contains_pair("Asset Name", owner_name, message) assert_contains_pair("Message", ipfs_hash, message) n1.clearmessages() n1_messages = n1.viewallmessages() assert_equal(0, len(n1_messages)) # n0 sends more messages on channels one and two n0.sendmessage(channel_one, ipfs_hash) n0.sendmessage(channel_two, ipfs_hash) n0.generate(1) self.sync_all() # n1 views then clears messages n1_messages = n1.viewallmessages() assert_equal(1, len(n1_messages)) message = n1_messages[0] assert_contains_pair("Asset Name", channel_one, message) assert_contains_pair("Message", ipfs_hash, message) n1.clearmessages() n1_messages = n1.viewallmessages() assert_equal(0, len(n1_messages)) # n1 unsubscribes n1.unsubscribefromchannel(owner_name) n1.unsubscribefromchannel(channel_one) assert_equal(0, len(n1.viewallmessagechannels())) # auto-subscribe / spam protection (first address use only) addr1 = n1.getnewaddress() n0.transfer(asset_name, 10, addr1) n0.generate(1) self.sync_all() n0.transfer(spam_name, 10, addr1) n1_channels = n1.viewallmessagechannels() assert_equal(1, len(n1_channels)) assert_contains(owner_name, n1_channels) assert_does_not_contain(spam_name, n1_channels) n1.unsubscribefromchannel(owner_name) # pre-existing messages (don't see w/o rescan) assert_equal(0, len(n1.viewallmessages())) n0.sendmessage(channel_two, ipfs_hash) n0.generate(1) self.sync_all() assert_equal(0, len(n1.viewallmessages())) n1.subscribetochannel(channel_two) assert_equal(0, len(n1.viewallmessages())) n0.sendmessage(channel_two, ipfs_hash) n0.generate(1) self.sync_all() assert_equal(1, len(n1.viewallmessages())) assert_contains_pair("Asset Name", channel_two, n1.viewallmessages()[0]) n1.clearmessages() n1.unsubscribefromchannel(channel_two)