Example #1
0
    def mine(self):
        print("Mining some blocks")
        daemon = Daemon()
        wallet = Wallet()

        daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 80)
        wallet.refresh()
Example #2
0
    def mine(self):
        print("Mining some blocks")
        daemon = Daemon()
        wallet = Wallet()

        daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 80)
        wallet.refresh()
Example #3
0
 def transfer(self):
     print('Creating transaction')
     self.wallet[0].refresh()
     dst = {'address': '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW', 'amount':123456789000}
     res = self.wallet[0].transfer([dst], get_tx_key = True)
     assert len(res.tx_hash) == 64
     assert len(res.tx_key) == 64
     daemon = Daemon()
     daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
     return (res.tx_hash, res.tx_key, 123456789000)
Example #4
0
 def transfer(self):
     print('Creating transaction')
     self.wallet[0].refresh()
     dst = {'address': '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW', 'amount':123456789000}
     res = self.wallet[0].transfer([dst], get_tx_key = True)
     assert len(res.tx_hash) == 64
     assert len(res.tx_key) == 64
     daemon = Daemon()
     daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
     return (res.tx_hash, res.tx_key, 123456789000)
Example #5
0
    def mine(self):
        print("Mining some blocks")
        daemon = Daemon()

        res = daemon.get_info()
        height = res.height

        daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 80)
        for i in range(len(self.wallet)):
            self.wallet[i].refresh()
            res = self.wallet[i].get_height()
            assert res.height == height + 80
Example #6
0
    def mine(self):
        print("Mining some blocks")
        daemon = Daemon()

        res = daemon.get_info()
        height = res.height

        daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 80)
        for i in range(len(self.wallet)):
            self.wallet[i].refresh()
            res = self.wallet[i].get_height()
            assert res.height == height + 80
Example #7
0
    def mine(self):
        print("Mining some blocks")
        daemon = Daemon()

        res = daemon.get_info()
        height = res.height

        daemon.generateblocks(
            'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
            80)
        for i in range(len(self.wallet)):
            self.wallet[i].refresh()
            res = self.wallet[i].get_height()
            assert res.height == height + 80
Example #8
0
    def submitblock(self):
        print("Test submitblock")

        daemon = Daemon()
        res = daemon.get_height()
        height = res.height
        res = daemon.generateblocks(
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
            5)
        assert len(res.blocks) == 5
        hashes = res.blocks
        blocks = []
        for block_hash in hashes:
            res = daemon.getblock(hash=block_hash)
            assert len(res.blob) > 0 and len(res.blob) % 2 == 0
            blocks.append(res.blob)
        res = daemon.get_height()
        assert res.height == height + 5
        res = daemon.pop_blocks(5)
        res = daemon.get_height()
        assert res.height == height
        for i in range(len(hashes)):
            block_hash = hashes[i]
            assert len(block_hash) == 64
            res = daemon.submitblock(blocks[i])
            res = daemon.get_height()
            assert res.height == height + i + 1
            assert res.hash == block_hash
Example #9
0
    def mine(self, blocks):
        assert blocks >= 1

        print("Generating", blocks, 'blocks')

        daemon = Daemon(idx = 2)

        # generate blocks
        res_generateblocks = daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', blocks)
Example #10
0
    def test_access_payment(self):
        print('Testing access payment')
        daemon = Daemon(idx=1)
        wallet = Wallet(idx=3)

        # Try random nonces till we find one that's valid so we get a load of credits
        res = daemon.rpc_access_info(client = self.get_signature())
        credits = res.credits
        cookie = res.cookie
        nonce = 0
        while credits <= 100:
            nonce += 1
            try:
                res = daemon.rpc_access_submit_nonce(nonce = nonce, cookie = cookie, client = self.get_signature())
                break
            except:
                pass
            assert nonce < 1000 # can't find both valid and invalid -> the RPC probably fails

        res = daemon.rpc_access_info(client = self.get_signature())
        credits = res.credits
        assert credits > 0

        res = daemon.get_info(client = self.get_signature())
        assert res.credits == credits - 1
        credits = res.credits

        res = daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 100)
        block_hashes = res.blocks

        # ask for 1 block -> 1 credit
        res = daemon.getblockheadersrange(0, 0, client = self.get_signature())
        assert res.credits == credits - 1
        credits = res.credits

        # ask for 100 blocks -> >1 credit
        res = daemon.getblockheadersrange(1, 100, client = self.get_signature())
        assert res.credits < credits - 1
        credits = res.credits

        # external users
        res = daemon.rpc_access_pay(payment = 1, paying_for = 'foo', client = self.get_signature())
        assert res.credits == credits - 1
        res = daemon.rpc_access_pay(payment = 4, paying_for = 'bar', client = self.get_signature())
        assert res.credits == credits - 5
        res = daemon.rpc_access_pay(payment = credits, paying_for = 'baz', client = self.get_signature())
        assert "PAYMENT REQUIRED" in res.status
        res = daemon.rpc_access_pay(payment = 2, paying_for = 'quux', client = self.get_signature())
        assert res.credits == credits - 7
        res = daemon.rpc_access_pay(payment = 3, paying_for = 'bar', client = self.get_signature())
        assert res.credits == credits - 10

        # that should be rejected because its cost is massive
        ok = False
        try: res = daemon.get_output_histogram(amounts = [], client = self.get_signature())
        except Exception as e: print('e: ' + str(e)); ok = "PAYMENT REQUIRED" in e.status
        assert ok or "PAYMENT REQUIRED" in res.status
Example #11
0
    def check_destinations(self):
        daemon = Daemon()

        print("Checking transaction destinations")

        dst = {'address': '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 'amount': 1000000000000}
        res = self.wallet[0].transfer([dst])
        assert len(res.tx_hash) == 64
        tx_hash = res.tx_hash
        for i in range(2):
            res = self.wallet[0].get_transfers(pending = True, out = True)
            l = [x for x in (res.pending if i == 0 else res.out) if x.txid == tx_hash]
            assert len(l) == 1
            e = l[0]
            assert len(e.destinations) == 1
            assert e.destinations[0].amount == 1000000000000
            assert e.destinations[0].address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'

            if i == 0:
                daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
                self.wallet[0].refresh()

        dst = {'address': '8AsN91rznfkBGTY8psSNkJBg9SZgxxGGRUhGwRptBhgr5XSQ1XzmA9m8QAnoxydecSh5aLJXdrgXwTDMMZ1AuXsN1EX5Mtm', 'amount': 1000000000000}
        res = self.wallet[0].transfer([dst])
        assert len(res.tx_hash) == 64
        tx_hash = res.tx_hash
        for i in range(2):
            res = self.wallet[0].get_transfers(pending = True, out = True)
            l = [x for x in (res.pending if i == 0 else res.out) if x.txid == tx_hash]
            assert len(l) == 1
            e = l[0]
            assert len(e.destinations) == 1
            assert e.destinations[0].amount == 1000000000000
            assert e.destinations[0].address == '8AsN91rznfkBGTY8psSNkJBg9SZgxxGGRUhGwRptBhgr5XSQ1XzmA9m8QAnoxydecSh5aLJXdrgXwTDMMZ1AuXsN1EX5Mtm'

            if i == 0:
                daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
                self.wallet[0].refresh()

        dst = {'address': '4BxSHvcgTwu25WooY4BVmgdcKwZu5EksVZSZkDd6ooxSVVqQ4ubxXkhLF6hEqtw96i9cf3cVfLw8UWe95bdDKfRQeYtPwLm1Jiw7AKt2LY', 'amount': 1000000000000}
        res = self.wallet[0].transfer([dst])
        assert len(res.tx_hash) == 64
        tx_hash = res.tx_hash
        for i in range(2):
            res = self.wallet[0].get_transfers(pending = True, out = True)
            l = [x for x in (res.pending if i == 0 else res.out) if x.txid == tx_hash]
            assert len(l) == 1
            e = l[0]
            assert len(e.destinations) == 1
            assert e.destinations[0].amount == 1000000000000
            assert e.destinations[0].address == '4BxSHvcgTwu25WooY4BVmgdcKwZu5EksVZSZkDd6ooxSVVqQ4ubxXkhLF6hEqtw96i9cf3cVfLw8UWe95bdDKfRQeYtPwLm1Jiw7AKt2LY'

            if i == 0:
                daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
                self.wallet[0].refresh()
Example #12
0
    def sweep_single(self):
        daemon = Daemon()

        print("Sending single output")

        daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
        self.wallet[0].refresh()
        res = self.wallet[0].incoming_transfers(transfer_type = 'available')
        for t in res.transfers:
            assert not t.spent
        assert len(res.transfers) > 8 # we mined a lot
        index = 8
        assert not res.transfers[index].spent
        assert res.transfers[index].amount > 0
        ki = res.transfers[index].key_image
        amount = res.transfers[index].amount
        daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 10) # ensure unlocked
        self.wallet[0].refresh()
        res = self.wallet[0].get_balance()
        balance = res.balance
        res = daemon.is_key_image_spent([ki])
        assert len(res.spent_status) == 1
        assert res.spent_status[0] == 0
        res = self.wallet[0].sweep_single('44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW', key_image = ki)
        assert len(res.tx_hash) == 64
        tx_hash = res.tx_hash
        res = daemon.is_key_image_spent([ki])
        assert len(res.spent_status) == 1
        assert res.spent_status[0] == 2
        daemon.generateblocks('44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW', 1)
        res = daemon.is_key_image_spent([ki])
        assert len(res.spent_status) == 1
        assert res.spent_status[0] == 1
        self.wallet[0].refresh()
        res = self.wallet[0].get_balance()
        new_balance = res.balance
        res = daemon.get_transactions([tx_hash], decode_as_json = True)
        assert len(res.txs) == 1
        tx = res.txs[0]
        assert tx.tx_hash == tx_hash
        assert not tx.in_pool
        assert len(tx.as_json) > 0
        try:
            j = json.loads(tx.as_json)
        except:
            j = None
        assert j
        assert new_balance == balance - amount
        assert len(j['vin']) == 1
        assert j['vin'][0]['key']['k_image'] == ki
        self.wallet[0].refresh()
        res = self.wallet[0].incoming_transfers(transfer_type = 'available')
        assert len([t for t in res.transfers if t.key_image == ki]) == 0
        res = self.wallet[0].incoming_transfers(transfer_type = 'unavailable')
        assert len([t for t in res.transfers if t.key_image == ki]) == 1
Example #13
0
    def sweep_single(self):
        daemon = Daemon()

        print("Sending single output")

        daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
        self.wallet[0].refresh()
        res = self.wallet[0].incoming_transfers(transfer_type = 'available')
        for t in res.transfers:
            assert not t.spent
        assert len(res.transfers) > 8 # we mined a lot
        index = 8
        assert not res.transfers[index].spent
        assert res.transfers[index].amount > 0
        ki = res.transfers[index].key_image
        amount = res.transfers[index].amount
        daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 10) # ensure unlocked
        self.wallet[0].refresh()
        res = self.wallet[0].get_balance()
        balance = res.balance
        res = self.wallet[0].incoming_transfers(transfer_type = 'all')
        res = self.wallet[0].sweep_single('44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW', key_image = ki)
        assert len(res.tx_hash) == 64
        tx_hash = res.tx_hash
        daemon.generateblocks('44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW', 1)
        self.wallet[0].refresh()
        res = self.wallet[0].get_balance()
        new_balance = res.balance
        res = daemon.get_transactions([tx_hash], decode_as_json = True)
        assert len(res.txs) == 1
        tx = res.txs[0]
        assert tx.tx_hash == tx_hash
        assert not tx.in_pool
        assert len(tx.as_json) > 0
        try:
            j = json.loads(tx.as_json)
        except:
            j = None
        assert j
        assert new_balance == balance - amount
        assert len(j['vin']) == 1
        assert j['vin'][0]['key']['k_image'] == ki
        self.wallet[0].refresh()
        res = self.wallet[0].incoming_transfers(transfer_type = 'available')
        assert len([t for t in res.transfers if t.key_image == ki]) == 0
        res = self.wallet[0].incoming_transfers(transfer_type = 'unavailable')
        assert len([t for t in res.transfers if t.key_image == ki]) == 1
Example #14
0
    def test_randomx(self):
        print("Test RandomX")

        daemon = Daemon()
        wallet = Wallet()

        res = daemon.get_height()
        daemon.pop_blocks(res.height - 1)
        daemon.flush_txpool()

        epoch = int(os.environ['SEEDHASH_EPOCH_BLOCKS'])
        lag = int(os.environ['SEEDHASH_EPOCH_LAG'])
        address = '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'

        # check we can generate blocks, and that the seed hash changes when expected
        res = daemon.getblocktemplate(address)
        first_seed_hash = res.seed_hash
        daemon.generateblocks(address, 1 + lag)
        res = daemon.mining_status()
        assert res.active == False
        assert res.pow_algorithm == 'RandomX'
        res = daemon.getblocktemplate(address)
        seed_hash = res.seed_hash
        t0 = time.time()
        daemon.generateblocks(address, epoch - 3)
        t0 = time.time() - t0
        res = daemon.get_info()
        assert res.height == lag + epoch - 1
        res = daemon.getblocktemplate(address)
        assert seed_hash == res.seed_hash
        t0 = time.time()
        daemon.generateblocks(address, 1)
        t0 = time.time() - t0
        res = daemon.get_info()
        assert res.height == lag + epoch
        daemon.generateblocks(address, 1)
        res = daemon.getblocktemplate(address)
        assert seed_hash != res.seed_hash
        new_seed_hash = res.seed_hash
        t0 = time.time()
        daemon.generateblocks(address, epoch - 1)
        t0 = time.time() - t0
        res = daemon.getblocktemplate(address)
        assert new_seed_hash == res.seed_hash
        daemon.generateblocks(address, 1)
        res = daemon.getblocktemplate(address)
        assert new_seed_hash != res.seed_hash
        new_seed_hash = res.seed_hash
        t0 = time.time()
        daemon.generateblocks(address, epoch - 1)
        t0 = time.time() - t0
        res = daemon.getblocktemplate(address)
        assert new_seed_hash == res.seed_hash
        daemon.generateblocks(address, 1)
        res = daemon.getblocktemplate(address)
        assert new_seed_hash != res.seed_hash
        #print('First mining: ' + str(t0))

        # pop all these blocks, and feed them again to monerod
        print('Recreating the chain')
        res = daemon.get_info()
        height = res.height
        assert height == lag + epoch * 3 + 1
        block_hashes = [
            x.hash for x in daemon.getblockheadersrange(0, height - 1).headers
        ]
        assert len(block_hashes) == height
        blocks = []
        for i in range(len(block_hashes)):
            res = daemon.getblock(height=i)
            assert res.block_header.hash == block_hashes[i]
            blocks.append(res.blob)
        daemon.pop_blocks(height)
        res = daemon.get_info()
        assert res.height == 1
        res = daemon.getblocktemplate(address)
        assert first_seed_hash == res.seed_hash
        t0 = time.time()
        for h in range(len(block_hashes)):
            res = daemon.submitblock(blocks[h])
        t0 = time.time() - t0
        res = daemon.get_info()
        assert height == res.height
        res = daemon.getblocktemplate(address)
        assert new_seed_hash != res.seed_hash
        res = daemon.pop_blocks(1)
        res = daemon.getblocktemplate(address)
        assert new_seed_hash == res.seed_hash
        #print('Submit: ' + str(t0))

        # start mining from the genesis block again
        print('Mining from genesis block again')
        res = daemon.get_height()
        top_hash = res.hash
        res = daemon.getblockheaderbyheight(0)
        genesis_block_hash = res.block_header.hash
        t0 = time.time()
        daemon.generateblocks(address,
                              height - 2,
                              prev_block=genesis_block_hash)
        t0 = time.time() - t0
        res = daemon.get_info()
        assert res.height == height - 1
        assert res.top_block_hash == top_hash
        #print('Second mining: ' + str(t0))

        # that one will cause a huge reorg
        print('Adding one to reorg')
        res = daemon.generateblocks(address, 1)
        assert len(res.blocks) == 1
        new_top_hash = res.blocks[0]
        res = daemon.get_info()
        assert res.height == height
        assert res.top_block_hash == new_top_hash
    def test_get_output_distribution(self):
        print("Test get_output_distribution")

        daemon = Daemon()

        res = daemon.get_output_distribution([0], 0, 0)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 0
        assert d.base == 0
        assert d.binary == False
        assert len(d.distribution) == 1
        assert d.distribution[0] == 0

        res = daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)

        res = daemon.get_output_distribution([0], 0, 0)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 0
        assert d.base == 0
        assert d.binary == False
        assert len(d.distribution) == 2
        assert d.distribution[0] == 0
        assert d.distribution[1] == 1

        res = daemon.pop_blocks(1)

        res = daemon.get_output_distribution([0], 0, 0)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 0
        assert d.base == 0
        assert d.binary == False
        assert len(d.distribution) == 1
        assert d.distribution[0] == 0

        res = daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 3)

        res = daemon.get_output_distribution([0], 0, 0, cumulative = True)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 0
        assert d.base == 0
        assert d.binary == False
        assert len(d.distribution) == 4
        assert d.distribution[0] == 0
        assert d.distribution[1] == 1
        assert d.distribution[2] == 2
        assert d.distribution[3] == 3

        # extend
        res = daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 80)

        res = daemon.get_output_distribution([0], 0, 0, cumulative = True)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 0
        assert d.base == 0
        assert d.binary == False
        assert len(d.distribution) == 84
        for h in range(len(d.distribution)):
            assert d.distribution[h] == h

        # pop and replace, this will do through the "trim and extend" path
        res = daemon.pop_blocks(2)
        self.wallet.refresh()
        dst = {'address': '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 'amount': 1000000000000}
        self.wallet.transfer([dst])
        res = daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
        for step in range(3): # the second will be cached, the third will also be cached, but we get it in non-cumulative mode
            res = daemon.get_output_distribution([0], 0, 0, cumulative = step < 3)
            assert len(res.distributions) == 1
            d = res.distributions[0]
            assert d.amount == 0
            assert d.base == 0
            assert d.binary == False
            assert len(d.distribution) == 83
            for h in range(len(d.distribution)):
                assert d.distribution[h] == (h if step < 3 else 1) + (2 if h == len(d.distribution) - 1 else 0)

        # start at 0, end earlier
        res = daemon.get_output_distribution([0], 0, 40, cumulative = True)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 0
        assert d.base == 0
        assert d.binary == False
        assert len(d.distribution) == 41
        for h in range(len(d.distribution)):
            assert d.distribution[h] == h

        # start after 0, end earlier
        res = daemon.get_output_distribution([0], 10, 20, cumulative = True)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 0
        assert d.base == 9
        assert d.binary == False
        assert len(d.distribution) == 11
        for h in range(len(d.distribution)):
            assert d.distribution[h] == 10 + h

        # straddling up
        res = daemon.get_output_distribution([0], 15, 25, cumulative = True)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 0
        assert d.base == 14
        assert d.binary == False
        assert len(d.distribution) == 11
        for h in range(len(d.distribution)):
            assert d.distribution[h] == 15 + h

        # straddling down
        res = daemon.get_output_distribution([0], 8, 18, cumulative = True)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 0
        assert d.base == 7
        assert d.binary == False
        assert len(d.distribution) == 11
        for h in range(len(d.distribution)):
            assert d.distribution[h] == 8 + h

        # encompassing
        res = daemon.get_output_distribution([0], 5, 20, cumulative = True)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 0
        assert d.base == 4
        assert d.binary == False
        assert len(d.distribution) == 16
        for h in range(len(d.distribution)):
            assert d.distribution[h] == 5 + h

        # single
        res = daemon.get_output_distribution([0], 2, 2, cumulative = True)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 0
        assert d.base == 1
        assert d.binary == False
        assert len(d.distribution) == 1
        assert d.distribution[0] == 2

        # a non existent amount
        res = daemon.get_output_distribution([1], 0, 0)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 1
        assert d.base == 0
        assert d.binary == False
        assert len(d.distribution) == 83
        for h in range(len(d.distribution)):
            assert d.distribution[h] == 0
Example #16
0
    def _test_generateblocks(self, blocks):
        assert blocks >= 2

        print("Test generating", blocks, 'blocks')

        daemon = Daemon()

        # check info/height before generating blocks
        res_info = daemon.get_info()
        height = res_info.height
        prev_block = res_info.top_block_hash
        res_height = daemon.get_height()
        assert res_height.height == height
        assert int(res_info.wide_cumulative_difficulty) == (
            res_info.cumulative_difficulty_top64 <<
            64) + res_info.cumulative_difficulty
        cumulative_difficulty = int(res_info.wide_cumulative_difficulty)

        # we should not see a block at height
        ok = False
        try:
            daemon.getblock(height)
        except:
            ok = True
        assert ok

        # generate blocks
        res_generateblocks = daemon.generateblocks(
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
            blocks)

        # check info/height after generateblocks blocks
        assert res_generateblocks.height == height + blocks - 1
        res_info = daemon.get_info()
        assert res_info.height == height + blocks
        assert res_info.top_block_hash != prev_block
        res_height = daemon.get_height()
        assert res_height.height == height + blocks

        # get the blocks, check they have the right height
        res_getblock = []
        for n in range(blocks):
            res_getblock.append(daemon.getblock(height + n))
            block_header = res_getblock[n].block_header
            assert abs(block_header.timestamp -
                       time.time()) < 10  # within 10 seconds
            assert block_header.height == height + n
            assert block_header.orphan_status == False
            assert block_header.depth == blocks - n - 1
            assert block_header.prev_hash == prev_block, prev_block
            assert int(block_header.wide_difficulty) == (
                block_header.difficulty_top64 << 64) + block_header.difficulty
            assert int(block_header.wide_cumulative_difficulty) == (
                block_header.cumulative_difficulty_top64 <<
                64) + block_header.cumulative_difficulty
            assert block_header.reward >= 600000000000  # tail emission
            cumulative_difficulty += int(block_header.wide_difficulty)
            assert cumulative_difficulty == int(
                block_header.wide_cumulative_difficulty)
            assert block_header.block_size > 0
            assert block_header.block_weight >= block_header.block_size
            assert block_header.long_term_weight > 0
            prev_block = block_header.hash

        # we should not see a block after that
        ok = False
        try:
            daemon.getblock(height + blocks)
        except:
            ok = True
        assert ok

        # getlastblockheader and by height/hash should return the same block
        res_getlastblockheader = daemon.getlastblockheader()
        assert res_getlastblockheader.block_header == block_header
        res_getblockheaderbyhash = daemon.getblockheaderbyhash(prev_block)
        assert res_getblockheaderbyhash.block_header == block_header
        res_getblockheaderbyheight = daemon.getblockheaderbyheight(height +
                                                                   blocks - 1)
        assert res_getblockheaderbyheight.block_header == block_header

        # getting a block template after that should have the right height, etc
        res_getblocktemplate = daemon.getblocktemplate(
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
        )
        assert res_getblocktemplate.height == height + blocks
        assert res_getblocktemplate.reserved_offset > 0
        assert res_getblocktemplate.prev_hash == res_info.top_block_hash
        assert res_getblocktemplate.expected_reward >= 600000000000
        assert len(res_getblocktemplate.blocktemplate_blob) > 0
        assert len(res_getblocktemplate.blockhashing_blob) > 0
        assert int(res_getblocktemplate.wide_difficulty) == (
            res_getblocktemplate.difficulty_top64 <<
            64) + res_getblocktemplate.difficulty

        # diff etc should be the same
        assert res_getblocktemplate.prev_hash == res_info.top_block_hash

        res_getlastblockheader = daemon.getlastblockheader()

        # pop a block
        res_popblocks = daemon.pop_blocks(1)
        assert res_popblocks.height == height + blocks - 1

        res_info = daemon.get_info()
        assert res_info.height == height + blocks - 1

        # getlastblockheader and by height/hash should return the previous block
        block_header = res_getblock[blocks - 2].block_header
        block_header.depth = 0  # this will be different, ignore it
        res_getlastblockheader = daemon.getlastblockheader()
        assert res_getlastblockheader.block_header == block_header
        res_getblockheaderbyhash = daemon.getblockheaderbyhash(
            block_header.hash)
        assert res_getblockheaderbyhash.block_header == block_header
        res_getblockheaderbyheight = daemon.getblockheaderbyheight(height +
                                                                   blocks - 2)
        assert res_getblockheaderbyheight.block_header == block_header

        # we should not see the popped block anymore
        ok = False
        try:
            daemon.getblock(height + blocks - 1)
        except:
            ok = True
        assert ok

        # get transactions
        res = daemon.get_info()
        assert res.height == height + blocks - 1
        nblocks = height + blocks - 1
        res = daemon.getblockheadersrange(0, nblocks - 1)
        assert len(res.headers) == nblocks
        assert res.headers[-1] == block_header
        txids = [x.miner_tx_hash for x in res.headers]
        res = daemon.get_transactions(txs_hashes=txids)
        assert len(res.txs) == nblocks
        assert not 'missed_txs' in res or len(res.missed_txs) == 0
        running_output_index = 0
        for i in range(len(txids)):
            tx = res.txs[i]
            assert tx.tx_hash == txids[i]
            assert not tx.double_spend_seen
            assert not tx.in_pool
            assert tx.block_height == i
            if i > 0:
                for idx in tx.output_indices:
                    assert idx == running_output_index
                    running_output_index += 1
                res_out = daemon.get_outs([{
                    'amount': 0,
                    'index': idx
                } for idx in tx.output_indices],
                                          get_txid=True)
                assert len(res_out.outs) == len(tx.output_indices)
                for out in res_out.outs:
                    assert len(out.key) == 64
                    assert len(out.mask) == 64
                    assert not out.unlocked
                    assert out.height == i
                    assert out.txid == txids[i]

        for i in range(height + nblocks - 1):
            res_sum = daemon.get_coinbase_tx_sum(i, 1)
            res_header = daemon.getblockheaderbyheight(i)
            assert res_sum.emission_amount == res_header.block_header.reward

        res = daemon.get_coinbase_tx_sum(0, 1)
        assert res.emission_amount == 17592186044415
        assert res.fee_amount == 0
        sum_blocks = height + nblocks - 1
        res = daemon.get_coinbase_tx_sum(0, sum_blocks)
        extrapolated = 17592186044415 + 17592186044415 * 2 * (sum_blocks - 1)
        assert res.emission_amount < extrapolated and res.emission_amount > extrapolated - 1e12
        assert res.fee_amount == 0
        sum_blocks_emission = res.emission_amount
        res = daemon.get_coinbase_tx_sum(1, sum_blocks)
        assert res.emission_amount == sum_blocks_emission - 17592186044415
        assert res.fee_amount == 0

        res = daemon.get_output_distribution([0, 1, 17592186044415], 0, 0)
        assert len(res.distributions) == 3
        for a in range(3):
            assert res.distributions[a].amount == [0, 1, 17592186044415][a]
            assert res.distributions[a].start_height == 0
            assert res.distributions[a].base == 0
            assert len(
                res.distributions[a].distribution) == height + nblocks - 1
            assert res.distributions[a].binary == False
            for i in range(height + nblocks - 1):
                assert res.distributions[a].distribution[i] == (
                    1 if i > 0 and a == 0 else 1 if a == 2 and i == 0 else 0)

        res = daemon.get_output_histogram([], min_count=0, max_count=0)
        assert len(res.histogram) == 2
        for i in range(2):
            assert res.histogram[i].amount in [0, 17592186044415]
            assert res.histogram[i].total_instances in [
                height + nblocks - 2, 1
            ]
            assert res.histogram[i].unlocked_instances == 0
            assert res.histogram[i].recent_instances == 0
Example #17
0
    def _test_alt_chains(self):
        print('Testing alt chains')
        daemon = Daemon()
        res = daemon.get_alt_blocks_hashes()
        starting_alt_blocks = res.blks_hashes if 'blks_hashes' in res else []
        res = daemon.get_info()
        root_block_hash = res.top_block_hash
        height = res.height
        prev_hash = res.top_block_hash
        res_template = daemon.getblocktemplate(
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
        )
        nonce = 0

        # 5 siblings
        alt_blocks = [None] * 5
        for i in range(len(alt_blocks)):
            res = daemon.generateblocks(
                '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
                1,
                prev_block=prev_hash,
                starting_nonce=nonce)
            assert res.height == height
            assert len(res.blocks) == 1
            txid = res.blocks[0]
            res = daemon.getblockheaderbyhash(txid)
            nonce = res.block_header.nonce
            print('mined ' +
                  ('alt' if res.block_header.orphan_status else 'tip') +
                  ' block ' + str(height) + ', nonce ' + str(nonce))
            assert res.block_header.prev_hash == prev_hash
            assert res.block_header.orphan_status == (i > 0)
            alt_blocks[i] = txid
            nonce += 1

        print('mining 3 on 1')
        # three more on [1]
        chain1 = []
        res = daemon.generateblocks(
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
            3,
            prev_block=alt_blocks[1],
            starting_nonce=nonce)
        assert res.height == height + 3
        assert len(res.blocks) == 3
        blk_hash = res.blocks[2]
        res = daemon.getblockheaderbyhash(blk_hash)
        nonce = res.block_header.nonce
        assert not res.block_header.orphan_status
        nonce += 1
        chain1.append(blk_hash)
        chain1.append(res.block_header.prev_hash)

        print('Checking alt blocks match')
        res = daemon.get_alt_blocks_hashes()
        assert len(res.blks_hashes) == len(starting_alt_blocks) + 4
        for txid in alt_blocks:
            assert txid in res.blks_hashes or txid == alt_blocks[1]

        print('mining 4 on 3')
        # 4 more on [3], the chain will reorg when we mine the 4th
        top_block_hash = blk_hash
        prev_block = alt_blocks[3]
        for i in range(4):
            res = daemon.generateblocks(
                '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
                1,
                prev_block=prev_block)
            assert res.height == height + 1 + i
            assert len(res.blocks) == 1
            prev_block = res.blocks[-1]
            res = daemon.getblockheaderbyhash(res.blocks[-1])
            assert res.block_header.orphan_status == (i < 3)

            res = daemon.get_info()
            assert res.height == ((height + 4) if i < 3 else height + 5)
            assert res.top_block_hash == (top_block_hash
                                          if i < 3 else prev_block)

        res = daemon.get_info()
        assert res.height == height + 5
        assert res.top_block_hash == prev_block

        print('Checking alt blocks match')
        res = daemon.get_alt_blocks_hashes()
        blks_hashes = res.blks_hashes
        assert len(blks_hashes) == len(starting_alt_blocks) + 7
        for txid in alt_blocks:
            assert txid in blks_hashes or txid == alt_blocks[3]
        for txid in chain1:
            assert txid in blks_hashes

        res = daemon.get_alternate_chains()
        assert len(res.chains) == 4
        tips = [chain.block_hash for chain in res.chains]
        for txid in tips:
            assert txid in blks_hashes
        for chain in res.chains:
            assert chain.length in [1, 4]
            assert chain.length == len(chain.block_hashes)
            assert chain.height == height + chain.length - 1  # all happen start at the same height
            assert chain.main_chain_parent_block == root_block_hash
        for txid in [alt_blocks[0], alt_blocks[2], alt_blocks[4]]:
            assert len([
                chain for chain in res.chains if chain.block_hash == txid
            ]) == 1
Example #18
0
    def transfer(self):
        daemon = Daemon()

        print("Creating transfer to self")

        dst = {'address': '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 'amount': 1000000000000}
        payment_id = '1234500000012345abcde00000abcdeff1234500000012345abcde00000abcde'

        start_balances = [0] * len(self.wallet)
        running_balances = [0] * len(self.wallet)
        for i in range(len(self.wallet)):
          res = self.wallet[i].get_balance()
          start_balances[i] = res.balance
          running_balances[i] = res.balance
          assert res.unlocked_balance <= res.balance
          if i == 0:
            assert res.blocks_to_unlock == 59 # we've been mining to it
          else:
            assert res.blocks_to_unlock == 0

        print ('Checking short payment IDs cannot be used when not in an integrated address')
        ok = False
        try: self.wallet[0].transfer([dst], ring_size = 11, payment_id = '1234567812345678', get_tx_key = False)
        except: ok = True
        assert ok

        print ('Checking empty destination is rejected')
        ok = False
        try: self.wallet[0].transfer([], ring_size = 11, get_tx_key = False)
        except: ok = True
        assert ok

        res = self.wallet[0].transfer([dst], ring_size = 11, payment_id = payment_id, get_tx_key = False)
        assert len(res.tx_hash) == 32*2
        txid = res.tx_hash
        assert len(res.tx_key) == 0
        assert res.amount > 0
        amount = res.amount
        assert res.fee > 0
        fee = res.fee
        assert len(res.tx_blob) == 0
        assert len(res.tx_metadata) == 0
        assert len(res.multisig_txset) == 0
        assert len(res.unsigned_txset) == 0
        unsigned_txset = res.unsigned_txset

        self.wallet[0].refresh()

        res = daemon.get_info()
        height = res.height

        res = self.wallet[0].get_transfers()
        assert len(res['in']) == height - 1 # coinbases
        assert not 'out' in res or len(res.out) == 0 # not mined yet
        assert len(res.pending) == 1
        assert not 'pool' in res or len(res.pool) == 0
        assert not 'failed' in res or len(res.failed) == 0
        for e in res['in']:
          assert e.type == 'block'
        e = res.pending[0]
        assert e.txid == txid
        assert e.payment_id == payment_id
        assert e.type == 'pending'
        assert e.unlock_time == 0
        assert e.subaddr_index.major == 0
        assert e.subaddr_indices == [{'major': 0, 'minor': 0}]
        assert e.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
        assert e.double_spend_seen == False
        assert e.confirmations == 0

        running_balances[0] -= 1000000000000 + fee

        res = self.wallet[0].get_balance()
        assert res.balance == running_balances[0]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 59

        daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
        res = daemon.getlastblockheader()
        running_balances[0] += res.block_header.reward
        self.wallet[0].refresh()

        running_balances[0] += 1000000000000

        res = self.wallet[0].get_transfers()
        assert len(res['in']) == height # coinbases
        assert len(res.out) == 1 # not mined yet
        assert not 'pending' in res or len(res.pending) == 0
        assert not 'pool' in res or len(res.pool) == 0
        assert not 'failed' in res or len(res.failed) == 0
        for e in res['in']:
          assert e.type == 'block'
        e = res.out[0]
        assert e.txid == txid
        assert e.payment_id == payment_id
        assert e.type == 'out'
        assert e.unlock_time == 0
        assert e.subaddr_index.major == 0
        assert e.subaddr_indices == [{'major': 0, 'minor': 0}]
        assert e.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
        assert e.double_spend_seen == False
        assert e.confirmations == 1

        res = self.wallet[0].get_height()
        wallet_height = res.height
        res = self.wallet[0].get_transfer_by_txid(txid)
        assert len(res.transfers) == 1
        assert res.transfers[0] == res.transfer
        t = res.transfer
        assert t.txid == txid
        assert t.payment_id == payment_id
        assert t.height == wallet_height - 1
        assert t.timestamp > 0
        assert t.amount == 0 # to self, so it's just "pay a fee" really
        assert t.fee == fee
        assert t.note == ''
        assert len(t.destinations) == 1
        assert t.destinations[0] == {'address': '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 'amount': 1000000000000}
        assert t.type == 'out'
        assert t.unlock_time == 0
        assert t.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
        assert t.double_spend_seen == False
        assert t.confirmations == 1

        res = self.wallet[0].get_balance()
        assert res.balance == running_balances[0]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 59

        print("Creating transfer to another, manual relay")

        dst = {'address': '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW', 'amount': 1000000000000}
        res = self.wallet[0].transfer([dst], ring_size = 11, payment_id = payment_id, get_tx_key = True, do_not_relay = True, get_tx_hex = True)
        assert len(res.tx_hash) == 32*2
        txid = res.tx_hash
        assert len(res.tx_key) == 32*2
        assert res.amount == 1000000000000
        amount = res.amount
        assert res.fee > 0
        fee = res.fee
        assert len(res.tx_blob) > 0
        assert len(res.tx_metadata) == 0
        assert len(res.multisig_txset) == 0
        assert len(res.unsigned_txset) == 0
        tx_blob = res.tx_blob

        res = daemon.send_raw_transaction(tx_blob)
        assert res.not_relayed == False
        assert res.low_mixin == False
        assert res.double_spend == False
        assert res.invalid_input == False
        assert res.invalid_output == False
        assert res.too_big == False
        assert res.overspend == False
        assert res.fee_too_low == False
        assert res.not_rct == False

        self.wallet[0].refresh()

        res = self.wallet[0].get_balance()
        assert res.balance == running_balances[0]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 59

        self.wallet[1].refresh()

        res = self.wallet[1].get_transfers()
        assert not 'in' in res or len(res['in']) == 0
        assert not 'out' in res or len(res.out) == 0
        assert not 'pending' in res or len(res.pending) == 0
        assert len(res.pool) == 1
        assert not 'failed' in res or len(res.failed) == 0
        e = res.pool[0]
        assert e.txid == txid
        assert e.payment_id == payment_id
        assert e.type == 'pool'
        assert e.unlock_time == 0
        assert e.subaddr_index.major == 0
        assert e.subaddr_indices == [{'major': 0, 'minor': 0}]
        assert e.address == '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW'
        assert e.double_spend_seen == False
        assert e.confirmations == 0
        assert e.amount == amount
        assert e.fee == fee

        daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
        res = daemon.getlastblockheader()
        running_balances[0] -= 1000000000000 + fee
        running_balances[0] += res.block_header.reward
        self.wallet[1].refresh()
        running_balances[1] += 1000000000000

        res = self.wallet[1].get_transfers()
        assert len(res['in']) == 1
        assert not 'out' in res or len(res.out) == 0
        assert not 'pending' in res or len(res.pending) == 0
        assert not 'pool' in res or len(res.pool) == 0
        assert not 'failed' in res or len(res.failed) == 0
        e = res['in'][0]
        assert e.txid == txid
        assert e.payment_id == payment_id
        assert e.type == 'in'
        assert e.unlock_time == 0
        assert e.subaddr_index.major == 0
        assert e.subaddr_indices == [{'major': 0, 'minor': 0}]
        assert e.address == '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW'
        assert e.double_spend_seen == False
        assert e.confirmations == 1
        assert e.amount == amount
        assert e.fee == fee

        res = self.wallet[1].get_balance()
        assert res.balance == running_balances[1]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 9

        print('Creating multi out transfer')

        self.wallet[0].refresh()

        dst0 = {'address': '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 'amount': 1000000000000}
        dst1 = {'address': '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW', 'amount': 1100000000000}
        dst2 = {'address': '46r4nYSevkfBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCLGwTerK', 'amount': 1200000000000}
        res = self.wallet[0].transfer([dst0, dst1, dst2], ring_size = 11, payment_id = payment_id, get_tx_key = True)
        assert len(res.tx_hash) == 32*2
        txid = res.tx_hash
        assert len(res.tx_key) == 32*2
        assert res.amount == 1000000000000 + 1100000000000 + 1200000000000
        amount = res.amount
        assert res.fee > 0
        fee = res.fee
        assert len(res.tx_blob) == 0
        assert len(res.tx_metadata) == 0
        assert len(res.multisig_txset) == 0
        assert len(res.unsigned_txset) == 0
        unsigned_txset = res.unsigned_txset

        running_balances[0] -= 1000000000000 + 1100000000000 + 1200000000000 + fee

        res = self.wallet[0].get_balance()
        assert res.balance == running_balances[0]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 59

        daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
        res = daemon.getlastblockheader()
        running_balances[0] += res.block_header.reward
        running_balances[0] += 1000000000000
        running_balances[1] += 1100000000000
        running_balances[2] += 1200000000000
        self.wallet[0].refresh()

        res = self.wallet[0].get_transfers()
        assert len(res['in']) == height + 2
        assert len(res.out) == 3
        assert not 'pending' in res or len(res.pending) == 0
        assert not 'pool' in res or len(res.pool) == 1
        assert not 'failed' in res or len(res.failed) == 0
        e = [o for o in res.out if o.txid == txid]
        assert len(e) == 1
        e = e[0]
        assert e.txid == txid
        assert e.payment_id == payment_id
        assert e.type == 'out'
        assert e.unlock_time == 0
        assert e.subaddr_index.major == 0
        assert e.subaddr_indices == [{'major': 0, 'minor': 0}]
        assert e.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
        assert e.double_spend_seen == False
        assert e.confirmations == 1

        assert e.amount == amount
        assert e.fee == fee

        res = self.wallet[0].get_balance()
        assert res.balance == running_balances[0]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 59

        self.wallet[1].refresh()
        res = self.wallet[1].get_transfers()
        assert len(res['in']) == 2
        assert not 'out' in res or len(res.out) == 0
        assert not 'pending' in res or len(res.pending) == 0
        assert not 'pool' in res or len(res.pool) == 0
        assert not 'failed' in res or len(res.failed) == 0
        e = [o for o in res['in'] if o.txid == txid]
        assert len(e) == 1
        e = e[0]
        assert e.txid == txid
        assert e.payment_id == payment_id
        assert e.type == 'in'
        assert e.unlock_time == 0
        assert e.subaddr_index.major == 0
        assert e.subaddr_indices == [{'major': 0, 'minor': 0}]
        assert e.address == '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW'
        assert e.double_spend_seen == False
        assert e.confirmations == 1
        assert e.amount == 1100000000000
        assert e.fee == fee

        res = self.wallet[1].get_balance()
        assert res.balance == running_balances[1]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 9

        self.wallet[2].refresh()
        res = self.wallet[2].get_transfers()
        assert len(res['in']) == 1
        assert not 'out' in res or len(res.out) == 0
        assert not 'pending' in res or len(res.pending) == 0
        assert not 'pool' in res or len(res.pool) == 0
        assert not 'failed' in res or len(res.failed) == 0
        e = [o for o in res['in'] if o.txid == txid]
        assert len(e) == 1
        e = e[0]
        assert e.txid == txid
        assert e.payment_id == payment_id
        assert e.type == 'in'
        assert e.unlock_time == 0
        assert e.subaddr_index.major == 0
        assert e.subaddr_indices == [{'major': 0, 'minor': 0}]
        assert e.address == '46r4nYSevkfBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCLGwTerK'
        assert e.double_spend_seen == False
        assert e.confirmations == 1
        assert e.amount == 1200000000000
        assert e.fee == fee

        res = self.wallet[2].get_balance()
        assert res.balance == running_balances[2]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 9

        print('Sending to integrated address')
        self.wallet[0].refresh()
        res = self.wallet[0].get_balance()
        i_pid = '1111111122222222'
        res = self.wallet[0].make_integrated_address(standard_address = '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW', payment_id = i_pid)
        i_address = res.integrated_address
        res = self.wallet[0].transfer([{'address': i_address, 'amount': 200000000}])
        assert len(res.tx_hash) == 32*2
        i_txid = res.tx_hash
        assert len(res.tx_key) == 32*2
        assert res.amount == 200000000
        i_amount = res.amount
        assert res.fee > 0
        fee = res.fee
        assert len(res.tx_blob) == 0
        assert len(res.tx_metadata) == 0
        assert len(res.multisig_txset) == 0
        assert len(res.unsigned_txset) == 0

        running_balances[0] -= 200000000 + fee

        res = self.wallet[0].get_balance()
        assert res.balance == running_balances[0]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 59

        daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
        res = daemon.getlastblockheader()
        running_balances[0] += res.block_header.reward
        running_balances[1] += 200000000

        self.wallet[0].refresh()
        res = self.wallet[0].get_balance()
        assert res.balance == running_balances[0]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 59

        self.wallet[1].refresh()
        res = self.wallet[1].get_balance()
        assert res.balance == running_balances[1]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 9

        self.wallet[2].refresh()
        res = self.wallet[2].get_balance()
        assert res.balance == running_balances[2]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 8

        daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
        res = daemon.getlastblockheader()
        running_balances[0] += res.block_header.reward

        self.wallet[0].refresh()
        res = self.wallet[0].get_balance()
        assert res.balance == running_balances[0]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 59

        self.wallet[1].refresh()
        res = self.wallet[1].get_balance()
        assert res.balance == running_balances[1]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 8

        self.wallet[2].refresh()
        res = self.wallet[2].get_balance()
        assert res.balance == running_balances[2]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 7
Example #19
0
    def check_txpool(self):
        daemon = Daemon()
        wallet = Wallet()

        res = daemon.get_info()
        height = res.height
        txpool_size = res.tx_pool_size

        self.check_empty_pool()

        txes = self.create_txes('46r4nYSevkfBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCLGwTerK', 5)

        res = daemon.get_info()
        assert res.tx_pool_size == txpool_size + 5
        txpool_size = res.tx_pool_size

        res = daemon.get_transaction_pool()
        assert len(res.transactions) == txpool_size
        total_bytes = 0
        total_fee = 0
        min_bytes = 99999999999999
        max_bytes = 0
        for txid in txes.keys():
            x = [x for x in res.transactions if x.id_hash == txid]
            assert len(x) == 1
            x = x[0]
            assert x.kept_by_block == False
            assert x.last_failed_id_hash == '0'*64
            assert x.double_spend_seen == False
            assert x.weight >= x.blob_size

            assert x.blob_size * 2 == len(txes[txid].tx_blob)
            assert x.fee == txes[txid].fee
            assert x.tx_blob == txes[txid].tx_blob

            total_bytes += x.blob_size
            total_fee += x.fee
            min_bytes = min(min_bytes, x.blob_size)
            max_bytes = max(max_bytes, x.blob_size)

        res = daemon.get_transaction_pool_hashes()
        assert sorted(res.tx_hashes) == sorted(txes.keys())

        res = daemon.get_transaction_pool_stats()
        assert res.pool_stats.bytes_total == total_bytes
        assert res.pool_stats.bytes_min == min_bytes
        assert res.pool_stats.bytes_max == max_bytes
        assert res.pool_stats.bytes_med >= min_bytes and res.pool_stats.bytes_med <= max_bytes
        assert res.pool_stats.fee_total == total_fee
        assert res.pool_stats.txs_total == len(txes)
        assert res.pool_stats.num_failing == 0
        assert res.pool_stats.num_10m == 0
        assert res.pool_stats.num_not_relayed == 0
        assert res.pool_stats.num_double_spends == 0

        print('Flushing 2 transactions')
        txes_keys = list(txes.keys())
        daemon.flush_txpool([txes_keys[1], txes_keys[3]])
        res = daemon.get_transaction_pool()
        assert len(res.transactions) == txpool_size - 2
        assert len([x for x in res.transactions if x.id_hash == txes_keys[1]]) == 0
        assert len([x for x in res.transactions if x.id_hash == txes_keys[3]]) == 0

        new_keys = list(txes.keys())
        new_keys.remove(txes_keys[1])
        new_keys.remove(txes_keys[3])
        res = daemon.get_transaction_pool_hashes()
        assert sorted(res.tx_hashes) == sorted(new_keys)

        res = daemon.get_transaction_pool()
        assert len(res.transactions) == len(new_keys)
        total_bytes = 0
        total_fee = 0
        min_bytes = 99999999999999
        max_bytes = 0
        for txid in new_keys:
            x = [x for x in res.transactions if x.id_hash == txid]
            assert len(x) == 1
            x = x[0]
            assert x.kept_by_block == False
            assert x.last_failed_id_hash == '0'*64
            assert x.double_spend_seen == False
            assert x.weight >= x.blob_size

            assert x.blob_size * 2 == len(txes[txid].tx_blob)
            assert x.fee == txes[txid].fee
            assert x.tx_blob == txes[txid].tx_blob

            total_bytes += x.blob_size
            total_fee += x.fee
            min_bytes = min(min_bytes, x.blob_size)
            max_bytes = max(max_bytes, x.blob_size)

        res = daemon.get_transaction_pool_stats()
        assert res.pool_stats.bytes_total == total_bytes
        assert res.pool_stats.bytes_min == min_bytes
        assert res.pool_stats.bytes_max == max_bytes
        assert res.pool_stats.bytes_med >= min_bytes and res.pool_stats.bytes_med <= max_bytes
        assert res.pool_stats.fee_total == total_fee
        assert res.pool_stats.txs_total == len(new_keys)
        assert res.pool_stats.num_failing == 0
        assert res.pool_stats.num_10m == 0
        assert res.pool_stats.num_not_relayed == 0
        assert res.pool_stats.num_double_spends == 0

        print('Flushing unknown transactions')
        unknown_txids = ['1'*64, '2'*64, '3'*64]
        daemon.flush_txpool(unknown_txids)
        res = daemon.get_transaction_pool()
        assert len(res.transactions) == txpool_size - 2

        print('Mining transactions')
        daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
        res = daemon.get_transaction_pool()
        assert not 'transactions' in res or len(res.transactions) == txpool_size - 5
        res = daemon.get_transaction_pool_hashes()
        assert not 'tx_hashes' in res or len(res.tx_hashes) == 0

        self.check_empty_pool()

        print('Popping block')
        daemon.pop_blocks(1)
        res = daemon.get_transaction_pool_hashes()
        assert sorted(res.tx_hashes) == sorted(new_keys)
        res = daemon.get_transaction_pool()
        assert len(res.transactions) == txpool_size - 2
        for txid in new_keys:
            x = [x for x in res.transactions if x.id_hash == txid]
            assert len(x) == 1
            x = x[0]
            assert x.kept_by_block == True
            assert x.last_failed_id_hash == '0'*64
            assert x.double_spend_seen == False
            assert x.weight >= x.blob_size

            assert x.blob_size * 2 == len(txes[txid].tx_blob)
            assert x.fee == txes[txid].fee
            assert x.tx_blob == txes[txid].tx_blob

        print('Checking relaying txes')
        res = daemon.get_transaction_pool_hashes()
        assert len(res.tx_hashes) > 0
        txid = res.tx_hashes[0]
        daemon.relay_tx([txid])
        res = daemon.get_transactions([txid])
        assert len(res.txs) == 1
        assert res.txs[0].tx_hash == txid
        assert res.txs[0].in_pool
        assert res.txs[0].relayed

        daemon.flush_txpool()
        self.check_empty_pool()
Example #20
0
    def transfer(self):
        daemon = Daemon()

        print("Creating transaction in hot wallet")

        dst = {
            'address':
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
            'amount': 1000000000000
        }
        payment_id = '1234500000012345abcde00000abcdeff1234500000012345abcde00000abcde'

        res = self.hot_wallet.transfer([dst],
                                       ring_size=11,
                                       payment_id=payment_id,
                                       get_tx_key=False)
        assert len(res.tx_hash) == 32 * 2
        txid = res.tx_hash
        assert len(res.tx_key) == 0
        assert res.amount > 0
        amount = res.amount
        assert res.fee > 0
        fee = res.fee
        assert len(res.tx_blob) == 0
        assert len(res.tx_metadata) == 0
        assert len(res.multisig_txset) == 0
        assert len(res.unsigned_txset) > 0
        unsigned_txset = res.unsigned_txset

        print 'Signing transaction with cold wallet'
        res = self.cold_wallet.sign_transfer(unsigned_txset)
        assert len(res.signed_txset) > 0
        signed_txset = res.signed_txset
        assert len(res.tx_hash_list) == 1
        txid = res.tx_hash_list[0]
        assert len(txid) == 64

        print 'Submitting transaction with hot wallet'
        res = self.hot_wallet.submit_transfer(signed_txset)
        assert len(res.tx_hash_list) > 0
        assert res.tx_hash_list[0] == txid

        res = self.hot_wallet.get_transfers()
        assert len([
            x for x in (res['pending'] if 'pending' in res else [])
            if x.txid == txid
        ]) == 1
        assert len([
            x for x in (res['out'] if 'out' in res else []) if x.txid == txid
        ]) == 0

        daemon.generateblocks(
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
            1)
        self.hot_wallet.refresh()

        res = self.hot_wallet.get_transfers()
        assert len([
            x for x in (res['pending'] if 'pending' in res else [])
            if x.txid == txid
        ]) == 0
        assert len([
            x for x in (res['out'] if 'out' in res else []) if x.txid == txid
        ]) == 1

        res = self.hot_wallet.get_tx_key(txid)
        assert len(
            res.tx_key
        ) == 0 or res.tx_key == '01' + '0' * 62  # identity is used as placeholder
        res = self.cold_wallet.get_tx_key(txid)
        assert len(res.tx_key) == 64
Example #21
0
    def transfer(self):
        daemon = Daemon()

        print("Creating transaction in hot wallet")

        dst = {'address': '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 'amount': 1000000000000}
        payment_id = '1234500000012345abcde00000abcdeff1234500000012345abcde00000abcde'

        self.hot_wallet.refresh()
        res = self.hot_wallet.export_outputs()
        self.cold_wallet.import_outputs(res.outputs_data_hex)
        res = self.cold_wallet.export_key_images(True)
        self.hot_wallet.import_key_images(res.signed_key_images, offset = res.offset)

        res = self.hot_wallet.transfer([dst], ring_size = 11, payment_id = payment_id, get_tx_key = False)
        assert len(res.tx_hash) == 32*2
        txid = res.tx_hash
        assert len(res.tx_key) == 0
        assert res.amount > 0
        amount = res.amount
        assert res.fee > 0
        fee = res.fee
        assert len(res.tx_blob) == 0
        assert len(res.tx_metadata) == 0
        assert len(res.multisig_txset) == 0
        assert len(res.unsigned_txset) > 0
        unsigned_txset = res.unsigned_txset

        print('Signing transaction with cold wallet')
        res = self.cold_wallet.describe_transfer(unsigned_txset = unsigned_txset)
        assert len(res.desc) == 1
        desc = res.desc[0]
        assert desc.amount_in >= amount + fee
        assert desc.amount_out == desc.amount_in - fee
        assert desc.ring_size == 11
        assert desc.unlock_time == 0
        assert desc.payment_id == payment_id
        assert desc.change_amount == desc.amount_in - 1000000000000 - fee
        assert desc.change_address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
        assert desc.fee == fee
        assert len(desc.recipients) == 1
        rec = desc.recipients[0]
        assert rec.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
        assert rec.amount == 1000000000000

        res = self.cold_wallet.sign_transfer(unsigned_txset)
        assert len(res.signed_txset) > 0
        signed_txset = res.signed_txset
        assert len(res.tx_hash_list) == 1
        txid = res.tx_hash_list[0]
        assert len(txid) == 64

        print('Submitting transaction with hot wallet')
        res = self.hot_wallet.submit_transfer(signed_txset)
        assert len(res.tx_hash_list) > 0
        assert res.tx_hash_list[0] == txid

        res = self.hot_wallet.get_transfers()
        assert len([x for x in (res['pending'] if 'pending' in res else []) if x.txid == txid]) == 1
        assert len([x for x in (res['out'] if 'out' in res else []) if x.txid == txid]) == 0

        daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
        self.hot_wallet.refresh()

        res = self.hot_wallet.get_transfers()
        assert len([x for x in (res['pending'] if 'pending' in res else []) if x.txid == txid]) == 0
        assert len([x for x in (res['out'] if 'out' in res else []) if x.txid == txid]) == 1

        res = self.hot_wallet.get_tx_key(txid)
        assert len(res.tx_key) == 0 or res.tx_key == '01' + '0' * 62 # identity is used as placeholder
        res = self.cold_wallet.get_tx_key(txid)
        assert len(res.tx_key) == 64
Example #22
0
    def transfer(self, signers):
        assert len(signers) >= 2

        daemon = Daemon()

        print("Creating multisig transaction from wallet " + str(signers[0]))

        dst = {
            'address':
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
            'amount': 1000000000000
        }
        res = self.wallet[signers[0]].transfer([dst])
        assert len(res.tx_hash) == 0  # not known yet
        txid = res.tx_hash
        assert len(res.tx_key) == 32 * 2
        assert res.amount > 0
        amount = res.amount
        assert res.fee > 0
        fee = res.fee
        assert len(res.tx_blob) == 0
        assert len(res.tx_metadata) == 0
        assert len(res.multisig_txset) > 0
        assert len(res.unsigned_txset) == 0
        multisig_txset = res.multisig_txset

        daemon.generateblocks(
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
            1)
        for i in range(len(self.wallet)):
            self.wallet[i].refresh()

        for i in range(len(signers[1:])):
            print('Signing multisig transaction with wallet ' +
                  str(signers[i + 1]))
            res = self.wallet[signers[i + 1]].describe_transfer(
                multisig_txset=multisig_txset)
            assert len(res.desc) == 1
            desc = res.desc[0]
            assert desc.amount_in >= amount + fee
            assert desc.amount_out == desc.amount_in - fee
            assert desc.ring_size == 11
            assert desc.unlock_time == 0
            assert desc.payment_id == '0000000000000000'
            assert desc.change_amount == desc.amount_in - 1000000000000 - fee
            assert desc.change_address == self.wallet_address
            assert desc.fee == fee
            assert len(desc.recipients) == 1
            rec = desc.recipients[0]
            assert rec.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
            assert rec.amount == 1000000000000

            res = self.wallet[signers[i + 1]].sign_multisig(multisig_txset)
            multisig_txset = res.tx_data_hex
            assert len(res.tx_hash_list if 'tx_hash_list' in res else []) == (
                i == len(signers[1:]) - 1)

            if i < len(signers[1:]) - 1:
                print(
                    'Submitting multisig transaction prematurely with wallet '
                    + str(signers[-1]))
                ok = False
                try:
                    self.wallet[signers[-1]].submit_multisig(multisig_txset)
                except:
                    ok = True
                assert ok

        print('Submitting multisig transaction with wallet ' +
              str(signers[-1]))
        res = self.wallet[signers[-1]].submit_multisig(multisig_txset)
        assert len(res.tx_hash_list) == 1
        txid = res.tx_hash_list[0]

        for i in range(len(self.wallet)):
            self.wallet[i].refresh()
            res = self.wallet[i].get_transfers()
            assert len([
                x for x in (res['pending'] if 'pending' in res else [])
                if x.txid == txid
            ]) == (1 if i == signers[-1] else 0)
            assert len([
                x for x in (res['out'] if 'out' in res else [])
                if x.txid == txid
            ]) == 0

        daemon.generateblocks(
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
            1)
        return txid
Example #23
0
    def check_txpool(self):
        daemon = Daemon()
        wallet = Wallet()

        res = daemon.get_info()
        height = res.height
        txpool_size = res.tx_pool_size

        txes = self.create_txes('46r4nYSevkfBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCLGwTerK', 5)

        res = daemon.get_info()
        assert res.tx_pool_size == txpool_size + 5
        txpool_size = res.tx_pool_size

        res = daemon.get_transaction_pool()
        assert len(res.transactions) == txpool_size
        for txid in txes.keys():
            x = [x for x in res.transactions if x.id_hash == txid]
            assert len(x) == 1
            x = x[0]
            assert x.kept_by_block == False
            assert x.last_failed_id_hash == '0'*64
            assert x.double_spend_seen == False
            assert x.weight >= x.blob_size

            assert x.blob_size * 2 == len(txes[txid].tx_blob)
            assert x.fee == txes[txid].fee
            assert x.tx_blob == txes[txid].tx_blob

        res = daemon.get_transaction_pool_hashes()
        assert sorted(res.tx_hashes) == sorted(txes.keys())

        print('Flushing 2 transactions')
        txes_keys = list(txes.keys())
        daemon.flush_txpool([txes_keys[1], txes_keys[3]])
        res = daemon.get_transaction_pool()
        assert len(res.transactions) == txpool_size - 2
        assert len([x for x in res.transactions if x.id_hash == txes_keys[1]]) == 0
        assert len([x for x in res.transactions if x.id_hash == txes_keys[3]]) == 0

        new_keys = list(txes.keys())
        new_keys.remove(txes_keys[1])
        new_keys.remove(txes_keys[3])
        res = daemon.get_transaction_pool_hashes()
        assert sorted(res.tx_hashes) == sorted(new_keys)

        print('Flushing unknown transactions')
        unknown_txids = ['1'*64, '2'*64, '3'*64]
        daemon.flush_txpool(unknown_txids)
        res = daemon.get_transaction_pool()
        assert len(res.transactions) == txpool_size - 2

        print('Mining transactions')
        daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
        res = daemon.get_transaction_pool()
        assert not 'transactions' in res or len(res.transactions) == txpool_size - 5
        res = daemon.get_transaction_pool_hashes()
        assert not 'tx_hashes' in res or len(res.tx_hashes) == 0

        print('Popping block')
        daemon.pop_blocks(1)
        res = daemon.get_transaction_pool_hashes()
        assert sorted(res.tx_hashes) == sorted(new_keys)
        res = daemon.get_transaction_pool()
        assert len(res.transactions) == txpool_size - 2
        for txid in new_keys:
            x = [x for x in res.transactions if x.id_hash == txid]
            assert len(x) == 1
            x = x[0]
            assert x.kept_by_block == True
            assert x.last_failed_id_hash == '0'*64
            assert x.double_spend_seen == False
            assert x.weight >= x.blob_size

            assert x.blob_size * 2 == len(txes[txid].tx_blob)
            assert x.fee == txes[txid].fee
            assert x.tx_blob == txes[txid].tx_blob
Example #24
0
    def transfer(self):
        daemon = Daemon()

        print("Creating transaction in hot wallet")

        dst = {
            'address':
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
            'amount': 1000000000000
        }

        self.hot_wallet.refresh()
        res = self.hot_wallet.export_outputs()
        self.cold_wallet.import_outputs(res.outputs_data_hex)
        res = self.cold_wallet.export_key_images(True)
        self.hot_wallet.import_key_images(res.signed_key_images,
                                          offset=res.offset)

        res = self.hot_wallet.transfer([dst], ring_size=11, get_tx_key=False)
        assert len(res.tx_hash) == 32 * 2
        txid = res.tx_hash
        assert len(res.tx_key) == 0
        assert res.amount > 0
        amount = res.amount
        assert res.fee > 0
        fee = res.fee
        assert len(res.tx_blob) == 0
        assert len(res.tx_metadata) == 0
        assert len(res.multisig_txset) == 0
        assert len(res.unsigned_txset) > 0
        unsigned_txset = res.unsigned_txset

        print('Signing transaction with cold wallet')
        res = self.cold_wallet.describe_transfer(unsigned_txset=unsigned_txset)
        assert len(res.desc) == 1
        desc = res.desc[0]
        assert desc.amount_in >= amount + fee
        assert desc.amount_out == desc.amount_in - fee
        assert desc.ring_size == 11
        assert desc.unlock_time == 0
        assert desc.payment_id in ['', '0000000000000000']
        assert desc.change_amount == desc.amount_in - 1000000000000 - fee
        assert desc.change_address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
        assert desc.fee == fee
        assert len(desc.recipients) == 1
        rec = desc.recipients[0]
        assert rec.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
        assert rec.amount == 1000000000000

        res = self.cold_wallet.sign_transfer(unsigned_txset)
        assert len(res.signed_txset) > 0
        signed_txset = res.signed_txset
        assert len(res.tx_hash_list) == 1
        txid = res.tx_hash_list[0]
        assert len(txid) == 64

        print('Submitting transaction with hot wallet')
        res = self.hot_wallet.submit_transfer(signed_txset)
        assert len(res.tx_hash_list) > 0
        assert res.tx_hash_list[0] == txid

        res = self.hot_wallet.get_transfers()
        assert len([
            x for x in (res['pending'] if 'pending' in res else [])
            if x.txid == txid
        ]) == 1
        assert len([
            x for x in (res['out'] if 'out' in res else []) if x.txid == txid
        ]) == 0

        daemon.generateblocks(
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
            1)
        self.hot_wallet.refresh()

        res = self.hot_wallet.get_transfers()
        assert len([
            x for x in (res['pending'] if 'pending' in res else [])
            if x.txid == txid
        ]) == 0
        assert len([
            x for x in (res['out'] if 'out' in res else []) if x.txid == txid
        ]) == 1

        res = self.hot_wallet.get_tx_key(txid)
        assert len(
            res.tx_key
        ) == 0 or res.tx_key == '01' + '0' * 62  # identity is used as placeholder
        res = self.cold_wallet.get_tx_key(txid)
        assert len(res.tx_key) == 64
Example #25
0
 def mine(self, address, blocks):
     print("Mining some blocks")
     daemon = Daemon()
     daemon.generateblocks(address, blocks)
Example #26
0
    def check_destinations(self):
        daemon = Daemon()

        print("Checking transaction destinations")

        dst = {
            'address':
            'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
            'amount': 1000000000000
        }
        res = self.wallet[0].transfer([dst])
        assert len(res.tx_hash) == 64
        tx_hash = res.tx_hash
        for i in range(2):
            res = self.wallet[0].get_transfers(pending=True, out=True)
            l = [
                x for x in (res.pending if i == 0 else res.out)
                if x.txid == tx_hash
            ]
            assert len(l) == 1
            e = l[0]
            assert len(e.destinations) == 1
            assert e.destinations[0].amount == 1000000000000
            assert e.destinations[
                0].address == 'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq'

            if i == 0:
                daemon.generateblocks(
                    'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
                    1)
                self.wallet[0].refresh()

        dst = {
            'address':
            'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
            'amount': 1000000000000
        }
        res = self.wallet[0].transfer([dst])
        assert len(res.tx_hash) == 64
        tx_hash = res.tx_hash
        for i in range(2):
            res = self.wallet[0].get_transfers(pending=True, out=True)
            l = [
                x for x in (res.pending if i == 0 else res.out)
                if x.txid == tx_hash
            ]
            assert len(l) == 1
            e = l[0]
            assert len(e.destinations) == 1
            assert e.destinations[0].amount == 1000000000000
            assert e.destinations[
                0].address == 'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq'

            if i == 0:
                daemon.generateblocks(
                    'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
                    1)
                self.wallet[0].refresh()

        dst = {
            'address':
            'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
            'amount': 1000000000000
        }
        res = self.wallet[0].transfer([dst])
        assert len(res.tx_hash) == 64
        tx_hash = res.tx_hash
        for i in range(2):
            res = self.wallet[0].get_transfers(pending=True, out=True)
            l = [
                x for x in (res.pending if i == 0 else res.out)
                if x.txid == tx_hash
            ]
            assert len(l) == 1
            e = l[0]
            assert len(e.destinations) == 1
            assert e.destinations[0].amount == 1000000000000
            assert e.destinations[
                0].address == 'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq'

            if i == 0:
                daemon.generateblocks(
                    'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
                    1)
                self.wallet[0].refresh()
    def test_get_output_distribution(self):
        print("Test get_output_distribution")

        daemon = Daemon()

        res = daemon.get_output_distribution([0], 0, 0)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 0
        assert d.base == 0
        assert d.binary == False
        assert len(d.distribution) == 1
        assert d.distribution[0] == 0

        res = daemon.generateblocks(
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
            1)

        res = daemon.get_output_distribution([0], 0, 0)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 0
        assert d.base == 0
        assert d.binary == False
        assert len(d.distribution) == 2
        assert d.distribution[0] == 0
        assert d.distribution[1] == 1

        res = daemon.pop_blocks(1)

        res = daemon.get_output_distribution([0], 0, 0)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 0
        assert d.base == 0
        assert d.binary == False
        assert len(d.distribution) == 1
        assert d.distribution[0] == 0

        res = daemon.generateblocks(
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
            3)

        res = daemon.get_output_distribution([0], 0, 0, cumulative=True)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 0
        assert d.base == 0
        assert d.binary == False
        assert len(d.distribution) == 4
        assert d.distribution[0] == 0
        assert d.distribution[1] == 1
        assert d.distribution[2] == 2
        assert d.distribution[3] == 3

        # extend
        res = daemon.generateblocks(
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
            80)

        res = daemon.get_output_distribution([0], 0, 0, cumulative=True)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 0
        assert d.base == 0
        assert d.binary == False
        assert len(d.distribution) == 84
        for h in range(len(d.distribution)):
            assert d.distribution[h] == h

        # pop and replace, this will do through the "trim and extend" path
        res = daemon.pop_blocks(2)
        self.wallet.refresh()
        dst = {
            'address':
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
            'amount': 1000000000000
        }
        self.wallet.transfer([dst])
        res = daemon.generateblocks(
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
            1)
        for step in range(
                3
        ):  # the second will be cached, the third will also be cached, but we get it in non-cumulative mode
            res = daemon.get_output_distribution([0],
                                                 0,
                                                 0,
                                                 cumulative=step < 3)
            assert len(res.distributions) == 1
            d = res.distributions[0]
            assert d.amount == 0
            assert d.base == 0
            assert d.binary == False
            assert len(d.distribution) == 83
            for h in range(len(d.distribution)):
                assert d.distribution[h] == (h if step < 3 else 1) + (
                    2 if h == len(d.distribution) - 1 else 0)

        # start at 0, end earlier
        res = daemon.get_output_distribution([0], 0, 40, cumulative=True)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 0
        assert d.base == 0
        assert d.binary == False
        assert len(d.distribution) == 41
        for h in range(len(d.distribution)):
            assert d.distribution[h] == h

        # start after 0, end earlier
        res = daemon.get_output_distribution([0], 10, 20, cumulative=True)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 0
        assert d.base == 9
        assert d.binary == False
        assert len(d.distribution) == 11
        for h in range(len(d.distribution)):
            assert d.distribution[h] == 10 + h

        # straddling up
        res = daemon.get_output_distribution([0], 15, 25, cumulative=True)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 0
        assert d.base == 14
        assert d.binary == False
        assert len(d.distribution) == 11
        for h in range(len(d.distribution)):
            assert d.distribution[h] == 15 + h

        # straddling down
        res = daemon.get_output_distribution([0], 8, 18, cumulative=True)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 0
        assert d.base == 7
        assert d.binary == False
        assert len(d.distribution) == 11
        for h in range(len(d.distribution)):
            assert d.distribution[h] == 8 + h

        # encompassing
        res = daemon.get_output_distribution([0], 5, 20, cumulative=True)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 0
        assert d.base == 4
        assert d.binary == False
        assert len(d.distribution) == 16
        for h in range(len(d.distribution)):
            assert d.distribution[h] == 5 + h

        # single
        res = daemon.get_output_distribution([0], 2, 2, cumulative=True)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 0
        assert d.base == 1
        assert d.binary == False
        assert len(d.distribution) == 1
        assert d.distribution[0] == 2

        # a non existent amount
        res = daemon.get_output_distribution([1], 0, 0)
        assert len(res.distributions) == 1
        d = res.distributions[0]
        assert d.amount == 1
        assert d.base == 0
        assert d.binary == False
        assert len(d.distribution) == 83
        for h in range(len(d.distribution)):
            assert d.distribution[h] == 0
Example #28
0
    def transfer(self, signers):
        assert len(signers) >= 2

        daemon = Daemon()

        print("Creating multisig transaction from wallet " + str(signers[0]))

        dst = {'address': '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 'amount': 1000000000000}
        res = self.wallet[signers[0]].transfer([dst])
        assert len(res.tx_hash) == 0 # not known yet
        txid = res.tx_hash
        assert len(res.tx_key) == 32*2
        assert res.amount > 0
        amount = res.amount
        assert res.fee > 0
        fee = res.fee
        assert len(res.tx_blob) == 0
        assert len(res.tx_metadata) == 0
        assert len(res.multisig_txset) > 0
        assert len(res.unsigned_txset) == 0
        multisig_txset = res.multisig_txset

        daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
        for i in range(len(self.wallet)):
          self.wallet[i].refresh()

        for i in range(len(signers[1:])):
          print('Signing multisig transaction with wallet ' + str(signers[i+1]))
          res = self.wallet[signers[i+1]].describe_transfer(multisig_txset = multisig_txset)
          assert len(res.desc) == 1
          desc = res.desc[0]
          assert desc.amount_in >= amount + fee
          assert desc.amount_out == desc.amount_in - fee
          assert desc.ring_size == 11
          assert desc.unlock_time == 0
          assert desc.payment_id == '0000000000000000'
          assert desc.change_amount == desc.amount_in - 1000000000000 - fee
          assert desc.change_address == self.wallet_address
          assert desc.fee == fee
          assert len(desc.recipients) == 1
          rec = desc.recipients[0]
          assert rec.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
          assert rec.amount == 1000000000000

          res = self.wallet[signers[i+1]].sign_multisig(multisig_txset)
          multisig_txset = res.tx_data_hex
          assert len(res.tx_hash_list if 'tx_hash_list' in res else []) == (i == len(signers[1:]) - 1)

          if i < len(signers[1:]) - 1:
            print('Submitting multisig transaction prematurely with wallet ' + str(signers[-1]))
            ok = False
            try: self.wallet[signers[-1]].submit_multisig(multisig_txset)
            except: ok = True
            assert ok

        print('Submitting multisig transaction with wallet ' + str(signers[-1]))
        res = self.wallet[signers[-1]].submit_multisig(multisig_txset)
        assert len(res.tx_hash_list) == 1
        txid = res.tx_hash_list[0]

        for i in range(len(self.wallet)):
          self.wallet[i].refresh()
          res = self.wallet[i].get_transfers()
          assert len([x for x in (res['pending'] if 'pending' in res else []) if x.txid == txid]) == (1 if i == signers[-1] else 0)
          assert len([x for x in (res['out'] if 'out' in res else []) if x.txid == txid]) == 0

        daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
        return txid
Example #29
0
    def test_p2p_reorg(self):
        print('Testing P2P reorg')
        daemon2 = Daemon(idx=2)
        daemon3 = Daemon(idx=3)

        # give sync some time
        time.sleep(1)

        res = daemon2.get_info()
        height = res.height
        assert height > 0
        top_block_hash = res.top_block_hash
        assert len(top_block_hash) == 64

        res = daemon3.get_info()
        assert res.height == height
        assert res.top_block_hash == top_block_hash

        # disconnect daemons and mine separately on both
        daemon2.out_peers(0)
        daemon3.out_peers(0)

        res = daemon2.generateblocks(
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
            2)
        res = daemon3.generateblocks(
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
            3)

        res = daemon2.get_info()
        assert res.height == height + 2
        daemon2_top_block_hash = res.top_block_hash
        assert daemon2_top_block_hash != top_block_hash
        res = daemon3.get_info()
        assert res.height == height + 3
        daemon3_top_block_hash = res.top_block_hash
        assert daemon3_top_block_hash != top_block_hash
        assert daemon3_top_block_hash != daemon2_top_block_hash

        # reconnect, daemon2 will now switch to daemon3's chain
        daemon2.out_peers(8)
        daemon3.out_peers(8)
        time.sleep(10)
        res = daemon2.get_info()
        assert res.height == height + 3
        assert res.top_block_hash == daemon3_top_block_hash

        # disconect, mine on daemon2 again more than daemon3
        daemon2.out_peers(0)
        daemon3.out_peers(0)

        res = daemon2.generateblocks(
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
            3)
        res = daemon3.generateblocks(
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
            2)

        res = daemon2.get_info()
        assert res.height == height + 6
        daemon2_top_block_hash = res.top_block_hash
        assert daemon2_top_block_hash != top_block_hash
        res = daemon3.get_info()
        assert res.height == height + 5
        daemon3_top_block_hash = res.top_block_hash
        assert daemon3_top_block_hash != top_block_hash
        assert daemon3_top_block_hash != daemon2_top_block_hash

        # reconnect, daemon3 will now switch to daemon2's chain
        daemon2.out_peers(8)
        daemon3.out_peers(8)
        time.sleep(5)
        res = daemon3.get_info()
        assert res.height == height + 6
        assert res.top_block_hash == daemon2_top_block_hash

        # disconnect and mine a lot on daemon3
        daemon2.out_peers(0)
        daemon3.out_peers(0)
        res = daemon3.generateblocks(
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
            500)

        # reconnect and wait for sync
        daemon2.out_peers(8)
        daemon3.out_peers(8)
        loops = 100
        while True:
            res2 = daemon2.get_info()
            res3 = daemon3.get_info()
            if res2.top_block_hash == res3.top_block_hash:
                break
            time.sleep(10)
            loops -= 1
            assert loops >= 0
Example #30
0
    def _test_generateblocks(self, blocks):
        assert blocks >= 2

        print "Test generating", blocks, 'blocks'

        daemon = Daemon()

        # check info/height before generating blocks
        res_info = daemon.get_info()
        height = res_info.height
        prev_block = res_info.top_block_hash
        res_height = daemon.get_height()
        assert res_height.height == height
        assert int(res_info.wide_cumulative_difficulty) == (res_info.cumulative_difficulty_top64 << 64) + res_info.cumulative_difficulty
        cumulative_difficulty = int(res_info.wide_cumulative_difficulty)

        # we should not see a block at height
        ok = False
        try: daemon.getblock(height)
        except: ok = True
        assert ok

        # generate blocks
        res_generateblocks = daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', blocks)

        # check info/height after generateblocks blocks
        assert res_generateblocks.height == height + blocks - 1
        res_info = daemon.get_info()
        assert res_info.height == height + blocks
        assert res_info.top_block_hash != prev_block
        res_height = daemon.get_height()
        assert res_height.height == height + blocks

        # get the blocks, check they have the right height
        res_getblock = []
        for n in range(blocks):
            res_getblock.append(daemon.getblock(height + n))
            block_header = res_getblock[n].block_header
            assert abs(block_header.timestamp - time.time()) < 10 # within 10 seconds
            assert block_header.height == height + n
            assert block_header.orphan_status == False
            assert block_header.depth == blocks - n - 1
            assert block_header.prev_hash == prev_block, prev_block
            assert int(block_header.wide_difficulty) == (block_header.difficulty_top64 << 64) + block_header.difficulty
            assert int(block_header.wide_cumulative_difficulty) == (block_header.cumulative_difficulty_top64 << 64) + block_header.cumulative_difficulty
            assert block_header.reward >= 600000000000 # tail emission
            cumulative_difficulty += int(block_header.wide_difficulty)
            assert cumulative_difficulty == int(block_header.wide_cumulative_difficulty)
            assert block_header.block_size > 0
            assert block_header.block_weight >= block_header.block_size
            assert block_header.long_term_weight > 0
            prev_block = block_header.hash

        # we should not see a block after that
        ok = False
        try: daemon.getblock(height + blocks)
        except: ok = True
        assert ok

        # getlastblockheader and by height/hash should return the same block
        res_getlastblockheader = daemon.getlastblockheader()
        assert res_getlastblockheader.block_header == block_header
        res_getblockheaderbyhash = daemon.getblockheaderbyhash(prev_block)
        assert res_getblockheaderbyhash.block_header == block_header
        res_getblockheaderbyheight = daemon.getblockheaderbyheight(height + blocks - 1)
        assert res_getblockheaderbyheight.block_header == block_header

        # getting a block template after that should have the right height, etc
        res_getblocktemplate = daemon.getblocktemplate('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm')
        assert res_getblocktemplate.height == height + blocks
        assert res_getblocktemplate.reserved_offset > 0
        assert res_getblocktemplate.prev_hash == res_info.top_block_hash
        assert res_getblocktemplate.expected_reward >= 600000000000
        assert len(res_getblocktemplate.blocktemplate_blob) > 0
        assert len(res_getblocktemplate.blockhashing_blob) > 0
        assert int(res_getblocktemplate.wide_difficulty) == (res_getblocktemplate.difficulty_top64 << 64) + res_getblocktemplate.difficulty

        # diff etc should be the same
        assert res_getblocktemplate.prev_hash == res_info.top_block_hash

        res_getlastblockheader = daemon.getlastblockheader()

        # pop a block
        res_popblocks = daemon.pop_blocks(1)
        assert res_popblocks.height == height + blocks - 1

        res_info = daemon.get_info()
        assert res_info.height == height + blocks - 1

        # getlastblockheader and by height/hash should return the previous block
        block_header = res_getblock[blocks - 2].block_header
        block_header.depth = 0   # this will be different, ignore it
        res_getlastblockheader = daemon.getlastblockheader()
        assert res_getlastblockheader.block_header == block_header
        res_getblockheaderbyhash = daemon.getblockheaderbyhash(block_header.hash)
        assert res_getblockheaderbyhash.block_header == block_header
        res_getblockheaderbyheight = daemon.getblockheaderbyheight(height + blocks - 2)
        assert res_getblockheaderbyheight.block_header == block_header

        # we should not see the popped block anymore
        ok = False
        try: daemon.getblock(height + blocks - 1)
        except: ok = True
        assert ok
Example #31
0
    def transfer(self):
        daemon = Daemon()

        print("Creating transfer to self")

        dst = {'address': '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 'amount': 1000000000000}
        payment_id = '1234500000012345abcde00000abcdeff1234500000012345abcde00000abcde'

        start_balances = [0] * len(self.wallet)
        running_balances = [0] * len(self.wallet)
        for i in range(len(self.wallet)):
          res = self.wallet[i].get_balance()
          start_balances[i] = res.balance
          running_balances[i] = res.balance
          assert res.unlocked_balance <= res.balance
          if i == 0:
            assert res.blocks_to_unlock == 59 # we've been mining to it
          else:
            assert res.blocks_to_unlock == 0

        print ('Checking short payment IDs cannot be used when not in an integrated address')
        ok = False
        try: self.wallet[0].transfer([dst], ring_size = 11, payment_id = '1234567812345678', get_tx_key = False)
        except: ok = True
        assert ok

        print ('Checking long payment IDs are rejected')
        ok = False
        try: self.wallet[0].transfer([dst], ring_size = 11, payment_id = payment_id, get_tx_key = False, get_tx_hex = True)
        except: ok = True
        assert ok

        print ('Checking empty destination is rejected')
        ok = False
        try: self.wallet[0].transfer([], ring_size = 11, get_tx_key = False)
        except: ok = True
        assert ok

        res = self.wallet[0].transfer([dst], ring_size = 11, get_tx_key = False, get_tx_hex = True)
        assert len(res.tx_hash) == 32*2
        txid = res.tx_hash
        assert len(res.tx_key) == 0
        assert res.amount > 0
        amount = res.amount
        assert res.fee > 0
        fee = res.fee
        assert len(res.tx_blob) > 0
        tx_weight = res.weight
        assert len(res.tx_metadata) == 0
        assert len(res.multisig_txset) == 0
        assert len(res.unsigned_txset) == 0
        unsigned_txset = res.unsigned_txset

        res = daemon.get_fee_estimate(10)
        assert res.fee > 0
        assert res.quantization_mask > 0
        expected_fee = (res.fee * 1 * tx_weight + res.quantization_mask - 1) // res.quantization_mask * res.quantization_mask
        assert abs(1 - fee / expected_fee) < 0.01

        self.wallet[0].refresh()

        res = daemon.get_info()
        height = res.height

        res = self.wallet[0].get_transfers()
        assert len(res['in']) == height - 1 # coinbases
        assert not 'out' in res or len(res.out) == 0 # not mined yet
        assert len(res.pending) == 1
        assert not 'pool' in res or len(res.pool) == 0
        assert not 'failed' in res or len(res.failed) == 0
        for e in res['in']:
          assert e.type == 'block'
        e = res.pending[0]
        assert e.txid == txid
        assert e.payment_id in ['', '0000000000000000']
        assert e.type == 'pending'
        assert e.unlock_time == 0
        assert e.subaddr_index.major == 0
        assert e.subaddr_indices == [{'major': 0, 'minor': 0}]
        assert e.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
        assert e.double_spend_seen == False
        assert not 'confirmations' in e or e.confirmations == 0

        running_balances[0] -= fee

        res = self.wallet[0].get_balance()
        assert res.balance == running_balances[0]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 59

        daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
        res = daemon.getlastblockheader()
        running_balances[0] += res.block_header.reward
        self.wallet[0].refresh()

        res = self.wallet[0].get_transfers()
        assert len(res['in']) == height # coinbases
        assert len(res.out) == 1 # not mined yet
        assert not 'pending' in res or len(res.pending) == 0
        assert not 'pool' in res or len(res.pool) == 0
        assert not 'failed' in res or len(res.failed) == 0
        for e in res['in']:
          assert e.type == 'block'
        e = res.out[0]
        assert e.txid == txid
        assert e.payment_id in ['', '0000000000000000']
        assert e.type == 'out'
        assert e.unlock_time == 0
        assert e.subaddr_index.major == 0
        assert e.subaddr_indices == [{'major': 0, 'minor': 0}]
        assert e.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
        assert e.double_spend_seen == False
        assert e.confirmations == 1

        res = self.wallet[0].get_height()
        wallet_height = res.height
        res = self.wallet[0].get_transfer_by_txid(txid)
        assert len(res.transfers) == 1
        assert res.transfers[0] == res.transfer
        t = res.transfer
        assert t.txid == txid
        assert t.payment_id in ['', '0000000000000000']
        assert t.height == wallet_height - 1
        assert t.timestamp > 0
        assert t.amount == 0 # to self, so it's just "pay a fee" really
        assert t.fee == fee
        assert t.note == ''
        assert len(t.destinations) == 1
        assert t.destinations[0] == {'address': '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 'amount': 1000000000000}
        assert t.type == 'out'
        assert t.unlock_time == 0
        assert t.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
        assert t.double_spend_seen == False
        assert t.confirmations == 1

        res = self.wallet[0].get_balance()
        assert res.balance == running_balances[0]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 59

        print("Creating transfer to another, manual relay")

        dst = {'address': '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW', 'amount': 1000000000000}
        res = self.wallet[0].transfer([dst], ring_size = 11, get_tx_key = True, do_not_relay = True, get_tx_hex = True)
        assert len(res.tx_hash) == 32*2
        txid = res.tx_hash
        assert len(res.tx_key) == 32*2
        assert res.amount == 1000000000000
        amount = res.amount
        assert res.fee > 0
        fee = res.fee
        assert len(res.tx_blob) > 0
        assert len(res.tx_metadata) == 0
        assert len(res.multisig_txset) == 0
        assert len(res.unsigned_txset) == 0
        tx_blob = res.tx_blob

        res = daemon.send_raw_transaction(tx_blob)
        assert res.not_relayed == False
        assert res.low_mixin == False
        assert res.double_spend == False
        assert res.invalid_input == False
        assert res.invalid_output == False
        assert res.too_big == False
        assert res.overspend == False
        assert res.fee_too_low == False

        self.wallet[0].refresh()

        res = self.wallet[0].get_balance()
        assert res.balance == running_balances[0]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 59

        self.wallet[1].refresh()

        res = self.wallet[1].get_transfers()
        assert not 'in' in res or len(res['in']) == 0
        assert not 'out' in res or len(res.out) == 0
        assert not 'pending' in res or len(res.pending) == 0
        assert len(res.pool) == 1
        assert not 'failed' in res or len(res.failed) == 0
        e = res.pool[0]
        assert e.txid == txid
        assert e.payment_id in ["", "0000000000000000"] # long payment IDs are now ignored
        assert e.type == 'pool'
        assert e.unlock_time == 0
        assert e.subaddr_index.major == 0
        assert e.subaddr_indices == [{'major': 0, 'minor': 0}]
        assert e.address == '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW'
        assert e.double_spend_seen == False
        assert not 'confirmations' in e or e.confirmations == 0
        assert e.amount == amount
        assert e.fee == fee

        daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
        res = daemon.getlastblockheader()
        running_balances[0] -= 1000000000000 + fee
        running_balances[0] += res.block_header.reward
        self.wallet[1].refresh()
        running_balances[1] += 1000000000000

        res = self.wallet[1].get_transfers()
        assert len(res['in']) == 1
        assert not 'out' in res or len(res.out) == 0
        assert not 'pending' in res or len(res.pending) == 0
        assert not 'pool' in res or len(res.pool) == 0
        assert not 'failed' in res or len(res.failed) == 0
        e = res['in'][0]
        assert e.txid == txid
        assert e.payment_id in ["", "0000000000000000"] # long payment IDs are now ignored
        assert e.type == 'in'
        assert e.unlock_time == 0
        assert e.subaddr_index.major == 0
        assert e.subaddr_indices == [{'major': 0, 'minor': 0}]
        assert e.address == '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW'
        assert e.double_spend_seen == False
        assert e.confirmations == 1
        assert e.amount == amount
        assert e.fee == fee

        res = self.wallet[1].get_balance()
        assert res.balance == running_balances[1]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 9

        print('Creating multi out transfer')

        self.wallet[0].refresh()

        dst0 = {'address': '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 'amount': 1000000000000}
        dst1 = {'address': '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW', 'amount': 1100000000000}
        dst2 = {'address': '46r4nYSevkfBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCLGwTerK', 'amount': 1200000000000}
        res = self.wallet[0].transfer([dst0, dst1, dst2], ring_size = 11, get_tx_key = True)
        assert len(res.tx_hash) == 32*2
        txid = res.tx_hash
        assert len(res.tx_key) == 32*2
        assert res.amount == 1000000000000 + 1100000000000 + 1200000000000
        amount = res.amount
        assert res.fee > 0
        fee = res.fee
        assert len(res.tx_blob) == 0
        assert len(res.tx_metadata) == 0
        assert len(res.multisig_txset) == 0
        assert len(res.unsigned_txset) == 0
        unsigned_txset = res.unsigned_txset

        running_balances[0] -= 1100000000000 + 1200000000000 + fee

        res = self.wallet[0].get_balance()
        assert res.balance == running_balances[0]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 59

        daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
        res = daemon.getlastblockheader()
        running_balances[0] += res.block_header.reward
        running_balances[1] += 1100000000000
        running_balances[2] += 1200000000000
        self.wallet[0].refresh()

        res = self.wallet[0].get_transfers()
        assert len(res['in']) == height + 2
        assert len(res.out) == 3
        assert not 'pending' in res or len(res.pending) == 0
        assert not 'pool' in res or len(res.pool) == 1
        assert not 'failed' in res or len(res.failed) == 0
        e = [o for o in res.out if o.txid == txid]
        assert len(e) == 1
        e = e[0]
        assert e.txid == txid
        assert e.payment_id in ["", "0000000000000000"] # long payment IDs are now ignored
        assert e.type == 'out'
        assert e.unlock_time == 0
        assert e.subaddr_index.major == 0
        assert e.subaddr_indices == [{'major': 0, 'minor': 0}]
        assert e.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
        assert e.double_spend_seen == False
        assert e.confirmations == 1

        assert e.amount == amount
        assert e.fee == fee

        res = self.wallet[0].get_balance()
        assert res.balance == running_balances[0]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 59

        self.wallet[1].refresh()
        res = self.wallet[1].get_transfers()
        assert len(res['in']) == 2
        assert not 'out' in res or len(res.out) == 0
        assert not 'pending' in res or len(res.pending) == 0
        assert not 'pool' in res or len(res.pool) == 0
        assert not 'failed' in res or len(res.failed) == 0
        e = [o for o in res['in'] if o.txid == txid]
        assert len(e) == 1
        e = e[0]
        assert e.txid == txid
        assert e.payment_id in ["", "0000000000000000"] # long payment IDs are now ignored
        assert e.type == 'in'
        assert e.unlock_time == 0
        assert e.subaddr_index.major == 0
        assert e.subaddr_indices == [{'major': 0, 'minor': 0}]
        assert e.address == '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW'
        assert e.double_spend_seen == False
        assert e.confirmations == 1
        assert e.amount == 1100000000000
        assert e.fee == fee

        res = self.wallet[1].get_balance()
        assert res.balance == running_balances[1]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 9

        self.wallet[2].refresh()
        res = self.wallet[2].get_transfers()
        assert len(res['in']) == 1
        assert not 'out' in res or len(res.out) == 0
        assert not 'pending' in res or len(res.pending) == 0
        assert not 'pool' in res or len(res.pool) == 0
        assert not 'failed' in res or len(res.failed) == 0
        e = [o for o in res['in'] if o.txid == txid]
        assert len(e) == 1
        e = e[0]
        assert e.txid == txid
        assert e.payment_id in ["", "0000000000000000"] # long payment IDs are now ignored
        assert e.type == 'in'
        assert e.unlock_time == 0
        assert e.subaddr_index.major == 0
        assert e.subaddr_indices == [{'major': 0, 'minor': 0}]
        assert e.address == '46r4nYSevkfBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCLGwTerK'
        assert e.double_spend_seen == False
        assert e.confirmations == 1
        assert e.amount == 1200000000000
        assert e.fee == fee

        res = self.wallet[2].get_balance()
        assert res.balance == running_balances[2]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 9

        print('Sending to integrated address')
        self.wallet[0].refresh()
        res = self.wallet[0].get_balance()
        i_pid = '1111111122222222'
        res = self.wallet[0].make_integrated_address(standard_address = '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW', payment_id = i_pid)
        i_address = res.integrated_address
        res = self.wallet[0].transfer([{'address': i_address, 'amount': 200000000}])
        assert len(res.tx_hash) == 32*2
        i_txid = res.tx_hash
        assert len(res.tx_key) == 32*2
        assert res.amount == 200000000
        i_amount = res.amount
        assert res.fee > 0
        fee = res.fee
        assert len(res.tx_blob) == 0
        assert len(res.tx_metadata) == 0
        assert len(res.multisig_txset) == 0
        assert len(res.unsigned_txset) == 0

        running_balances[0] -= 200000000 + fee

        res = self.wallet[0].get_balance()
        assert res.balance == running_balances[0]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 59

        daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
        res = daemon.getlastblockheader()
        running_balances[0] += res.block_header.reward
        running_balances[1] += 200000000

        self.wallet[0].refresh()
        res = self.wallet[0].get_balance()
        assert res.balance == running_balances[0]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 59

        self.wallet[1].refresh()
        res = self.wallet[1].get_balance()
        assert res.balance == running_balances[1]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 9

        self.wallet[2].refresh()
        res = self.wallet[2].get_balance()
        assert res.balance == running_balances[2]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 8

        daemon.generateblocks('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', 1)
        res = daemon.getlastblockheader()
        running_balances[0] += res.block_header.reward

        self.wallet[0].refresh()
        res = self.wallet[0].get_balance()
        assert res.balance == running_balances[0]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 59

        self.wallet[1].refresh()
        res = self.wallet[1].get_balance()
        assert res.balance == running_balances[1]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 8

        self.wallet[2].refresh()
        res = self.wallet[2].get_balance()
        assert res.balance == running_balances[2]
        assert res.unlocked_balance <= res.balance
        assert res.blocks_to_unlock == 7
Example #32
0
    def check_txpool(self):
        daemon = Daemon()
        wallet = Wallet()

        res = daemon.get_info()
        height = res.height
        txpool_size = res.tx_pool_size

        txes = self.create_txes(
            '46r4nYSevkfBUMhuykdK3gQ98XDqDTYW1hNLaXNvjpsJaSbNtdXh1sKMsdVgqkaihChAzEy29zEDPMR3NHQvGoZCLGwTerK',
            5)

        res = daemon.get_info()
        assert res.tx_pool_size == txpool_size + 5
        txpool_size = res.tx_pool_size

        res = daemon.get_transaction_pool()
        assert len(res.transactions) == txpool_size
        for txid in txes.keys():
            x = [x for x in res.transactions if x.id_hash == txid]
            assert len(x) == 1
            x = x[0]
            assert x.kept_by_block == False
            assert x.last_failed_id_hash == '0' * 64
            assert x.double_spend_seen == False
            assert x.weight >= x.blob_size

            assert x.blob_size * 2 == len(txes[txid].tx_blob)
            assert x.fee == txes[txid].fee
            assert x.tx_blob == txes[txid].tx_blob

        res = daemon.get_transaction_pool_hashes()
        assert sorted(res.tx_hashes) == sorted(txes.keys())

        print('Flushing 2 transactions')
        txes_keys = list(txes.keys())
        daemon.flush_txpool([txes_keys[1], txes_keys[3]])
        res = daemon.get_transaction_pool()
        assert len(res.transactions) == txpool_size - 2
        assert len([x for x in res.transactions
                    if x.id_hash == txes_keys[1]]) == 0
        assert len([x for x in res.transactions
                    if x.id_hash == txes_keys[3]]) == 0

        new_keys = list(txes.keys())
        new_keys.remove(txes_keys[1])
        new_keys.remove(txes_keys[3])
        res = daemon.get_transaction_pool_hashes()
        assert sorted(res.tx_hashes) == sorted(new_keys)

        print('Flushing unknown transactions')
        unknown_txids = ['1' * 64, '2' * 64, '3' * 64]
        daemon.flush_txpool(unknown_txids)
        res = daemon.get_transaction_pool()
        assert len(res.transactions) == txpool_size - 2

        print('Mining transactions')
        daemon.generateblocks(
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
            1)
        res = daemon.get_transaction_pool()
        assert not 'transactions' in res or len(
            res.transactions) == txpool_size - 5
        res = daemon.get_transaction_pool_hashes()
        assert not 'tx_hashes' in res or len(res.tx_hashes) == 0

        print('Popping block')
        daemon.pop_blocks(1)
        res = daemon.get_transaction_pool_hashes()
        assert sorted(res.tx_hashes) == sorted(new_keys)
        res = daemon.get_transaction_pool()
        assert len(res.transactions) == txpool_size - 2
        for txid in new_keys:
            x = [x for x in res.transactions if x.id_hash == txid]
            assert len(x) == 1
            x = x[0]
            assert x.kept_by_block == True
            assert x.last_failed_id_hash == '0' * 64
            assert x.double_spend_seen == False
            assert x.weight >= x.blob_size

            assert x.blob_size * 2 == len(txes[txid].tx_blob)
            assert x.fee == txes[txid].fee
            assert x.tx_blob == txes[txid].tx_blob
Example #33
0
 def mine(self, address, blocks):
     print("Mining some blocks")
     daemon = Daemon()
     daemon.generateblocks(address, blocks)
Example #34
0
    def sweep_single(self):
        daemon = Daemon()

        print("Sending single output")

        daemon.generateblocks(
            'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
            1)
        self.wallet[0].refresh()
        res = self.wallet[0].incoming_transfers(transfer_type='available')
        for t in res.transfers:
            assert not t.spent
        assert len(res.transfers) > 8  # we mined a lot
        index = 8
        assert not res.transfers[index].spent
        assert res.transfers[index].amount > 0
        ki = res.transfers[index].key_image
        amount = res.transfers[index].amount
        daemon.generateblocks(
            'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
            10)  # ensure unlocked
        self.wallet[0].refresh()
        res = self.wallet[0].get_balance()
        balance = res.balance
        res = daemon.is_key_image_spent([ki])
        assert len(res.spent_status) == 1
        assert res.spent_status[0] == 0
        res = self.wallet[0].sweep_single(
            'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
            key_image=ki)
        assert len(res.tx_hash) == 64
        tx_hash = res.tx_hash
        res = daemon.is_key_image_spent([ki])
        assert len(res.spent_status) == 1
        assert res.spent_status[0] == 2
        daemon.generateblocks(
            'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
            1)
        res = daemon.is_key_image_spent([ki])
        assert len(res.spent_status) == 1
        assert res.spent_status[0] == 1
        self.wallet[0].refresh()
        res = self.wallet[0].get_balance()
        new_balance = res.balance
        res = daemon.get_transactions([tx_hash], decode_as_json=True)
        assert len(res.txs) == 1
        tx = res.txs[0]
        assert tx.tx_hash == tx_hash
        assert not tx.in_pool
        assert len(tx.as_json) > 0
        try:
            j = json.loads(tx.as_json)
        except:
            j = None
        assert j
        assert new_balance == balance - amount
        assert len(j['vin']) == 1
        assert j['vin'][0]['key']['k_image'] == ki
        self.wallet[0].refresh()
        res = self.wallet[0].incoming_transfers(transfer_type='available')
        assert len([t for t in res.transfers if t.key_image == ki]) == 0
        res = self.wallet[0].incoming_transfers(transfer_type='unavailable')
        assert len([t for t in res.transfers if t.key_image == ki]) == 1