Esempio n. 1
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
Esempio n. 2
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
Esempio n. 3
0
    def run_test(self):
        print('Testing bans')

        daemon = Daemon()
        res = daemon.get_bans()
        assert 'bans' not in res or len(res.bans) == 0

        daemon.set_bans([{'host': '1.2.3.4', 'ban': True, 'seconds': 100}])
        res = daemon.get_bans()
        assert len(res.bans) == 1
        assert res.bans[0].host == '1.2.3.4'
        assert res.bans[0].seconds >= 98 and res.bans[0].seconds <= 100 # allow for slow RPC

        daemon.set_bans([{'host': '5.6.7.8', 'ban': True, 'seconds': 100}])
        res = daemon.get_bans()
        assert len(res.bans) == 2
        for i in range(2):
          assert res.bans[i].host == '1.2.3.4' or res.bans[i].host == '5.6.7.8'
          assert res.bans[i].seconds >= 7 and res.bans[0].seconds <= 100 # allow for slow RPC

        daemon.set_bans([{'host': '1.2.3.4', 'ban': False}])
        res = daemon.get_bans()
        assert len(res.bans) == 1
        assert res.bans[0].host == '5.6.7.8'
        assert res.bans[0].seconds >= 98 and res.bans[0].seconds <= 100 # allow for slow RPC

        time.sleep(2)

        res = daemon.get_bans()
        assert len(res.bans) == 1
        assert res.bans[0].host == '5.6.7.8'
        assert res.bans[0].seconds >= 96 and res.bans[0].seconds <= 98 # allow for slow RPC

        daemon.set_bans([{'host': '3.4.5.6', 'ban': False}])
        res = daemon.get_bans()
        assert len(res.bans) == 1
        assert res.bans[0].host == '5.6.7.8'
        assert res.bans[0].seconds >= 96 and res.bans[0].seconds <= 98 # allow for slow RPC

        daemon.set_bans([{'host': '3.4.5.6', 'ban': True, 'seconds': 2}])
        res = daemon.get_bans()
        assert len(res.bans) == 2
        for i in range(2):
          assert res.bans[i].host == '5.6.7.8' or res.bans[i].host == '3.4.5.6'
          if res.bans[i].host == '5.6.7.8':
            assert res.bans[i].seconds >= 96 and res.bans[0].seconds <= 98 # allow for slow RPC
          else:
            assert res.bans[i].seconds >= 1 and res.bans[0].seconds <= 2 # allow for slow RPC

        time.sleep(2)
        res = daemon.get_bans()
        assert len(res.bans) == 1
        assert res.bans[0].host == '5.6.7.8'
        assert res.bans[0].seconds >= 94 and res.bans[0].seconds <= 96 # allow for slow RPC

        daemon.set_bans([{'host': '5.6.7.8', 'ban': True, 'seconds': 20}])
        res = daemon.get_bans()
        assert len(res.bans) == 1
        assert res.bans[0].host == '5.6.7.8'
        assert res.bans[0].seconds >= 18 and res.bans[0].seconds <= 20 # allow for slow RPC

        daemon.set_bans([{'host': '5.6.7.8', 'ban': True, 'seconds': 200}])
        res = daemon.get_bans()
        assert len(res.bans) == 1
        assert res.bans[0].host == '5.6.7.8'
        assert res.bans[0].seconds >= 198 and res.bans[0].seconds <= 200 # allow for slow RPC

        daemon.set_bans([{'host': '5.6.7.8', 'ban': False}])
        res = daemon.get_bans()
        assert 'bans' not in res or len(res.bans) == 0
Esempio n. 4
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

        print('Saving blockchain explicitely')
        daemon.save_bc()
Esempio n. 5
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
Esempio n. 6
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
Esempio n. 7
0
    def mine(self, via_daemon):
        print("Test mining via " + ("daemon" if via_daemon else "wallet"))

        cores_init = multiprocessing.cpu_count()  # RX init uses all cores
        cores_mine = 1  # Mining uses a parametric number of cores
        time_pi_single_cpu = self.measure_cpu_power_get_time(cores_mine)
        time_pi_all_cores = self.measure_cpu_power_get_time(cores_init)
        # This is the last measurement, since it takes very little time and can be placed timewise-closer to the mining itself.
        available_ram = self.get_available_ram(
        )  # So far no ideas how to use this var, other than printing it

        start = monotonic.monotonic()
        daemon = Daemon()
        wallet = Wallet()

        # check info/height/balance before generating blocks
        res_info = daemon.get_info()
        initial_height = res_info.height
        res_getbalance = wallet.get_balance()
        prev_balance = res_getbalance.balance

        res_status = daemon.mining_status()

        if via_daemon:
            res = daemon.start_mining(
                '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
                threads_count=1)
        else:
            res = wallet.start_mining(threads_count=cores_mine)

        res_status = daemon.mining_status()
        assert res_status.active == True
        assert res_status.threads_count == cores_mine
        assert res_status.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
        assert res_status.is_background_mining_enabled == False
        assert res_status.block_reward >= 600000000000

        # wait till we mined a few of them
        target_height = initial_height + 5
        height = initial_height
        """
        Randomx init has high variance on CI machines due to noisy neighbors, 
        taking up resources in parallel (including by our own jobs).
        
        Mining is organized in the following scheme:
            1) first loop's pass: RandomX init and mining
            2) every next pass:   only mining
        Pass 1) takes much more time than pass 2)
        Pass 1) uses all cores, pass 2) just one (currently)
        For the above reasons both passes need separate timeouts and adjustments.
        After the first pass, the timeout is being reset to a lower value.
        """
        def calc_timeout(seconds_constant, time_pi, cores):
            """
            The time it took to calculate pi under certain conditions 
            is proportional to the time it will take to calculate the real job.
            
            The number of cores used decreases the time almost linearly.
            """
            timeout = float(seconds_constant) * time_pi / float(cores)
            return timeout

        timeout_base_init = 60  # RX init needs more time
        timeout_base_mine = 20
        timeout_init = calc_timeout(timeout_base_init, time_pi_all_cores,
                                    cores_init)
        timeout_mine = calc_timeout(timeout_base_mine, time_pi_single_cpu,
                                    cores_mine)

        msg = "Timeout for {} adjusted for the currently available CPU power, is {:.1f} s"
        print(msg.format("init,  ", timeout_init))
        print(msg.format("mining,", timeout_mine))

        timeout = timeout_init
        rx_inited = False  # Gets initialized in the first pass of the below loop
        while height < target_height:
            seen_height = height
            for _ in range(int(math.ceil(timeout))):
                time.sleep(1)
                seconds_passed = monotonic.monotonic() - start
                height = daemon.get_info().height
                if height > seen_height:
                    break
            else:
                assert False, 'Failed to mine successor to block %d (initial block = %d) after %d s. RX initialized = %r' % (
                    seen_height, initial_height, round(seconds_passed),
                    rx_inited)
            if not rx_inited:
                rx_inited = True
                timeout = timeout_mine  # Resetting the timeout after first mined block and RX init
                self.print_time_taken(start, "RX init + mining 1st block")
            else:
                self.print_time_taken(start, "mining iteration")

        self.print_time_taken(start, "mining total")

        if via_daemon:
            res = daemon.stop_mining()
        else:
            res = wallet.stop_mining()

        res_status = daemon.mining_status()
        assert res_status.active == False

        res_info = daemon.get_info()
        new_height = res_info.height

        wallet.refresh()
        res_getbalance = wallet.get_balance()
        balance = res_getbalance.balance
        assert balance >= prev_balance + (new_height -
                                          initial_height) * 600000000000

        if via_daemon:
            res = daemon.start_mining(
                '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
                threads_count=1,
                do_background_mining=True)
        else:
            res = wallet.start_mining(threads_count=1,
                                      do_background_mining=True)
        res_status = daemon.mining_status()
        assert res_status.active == True
        assert res_status.threads_count == 1
        assert res_status.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
        assert res_status.is_background_mining_enabled == True
        assert res_status.block_reward >= 600000000000

        # don't wait, might be a while if the machine is busy, which it probably is
        if via_daemon:
            res = daemon.stop_mining()
        else:
            res = wallet.stop_mining()
        res_status = daemon.mining_status()
        assert res_status.active == False
Esempio n. 8
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
Esempio n. 9
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()
Esempio n. 10
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
Esempio n. 11
0
    def check_double_spend_detection(self):
        print('Checking double spend detection')
        txes = [[None, None], [None, None]]
        for i in range(2):
            self.wallet[0].restore_deterministic_wallet(
                seed=
                'upbeat wade toenail italics maverick anybody eluded altitude tumbling emotion against okay inkling ankle karate stunning doing verification slid zinger cucumber blender dual extra wade verification'
            )
            self.wallet[0].refresh()
            res = self.wallet[0].get_balance()
            unlocked_balance = res.unlocked_balance
            res = self.wallet[0].sweep_all(
                address=
                'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
                do_not_relay=True,
                get_tx_hex=True)
            assert len(res.tx_hash_list) == 1
            assert len(res.tx_hash_list[0]) == 32 * 2
            txes[i][0] = res.tx_hash_list[0]
            assert len(res.fee_list) == 1
            assert res.fee_list[0] > 0
            assert len(res.amount_list) == 1
            assert res.amount_list[0] == unlocked_balance - res.fee_list[0]
            assert len(res.tx_blob_list) > 0
            assert len(res.tx_blob_list[0]) > 0
            assert not 'tx_metadata_list' in res or len(
                res.tx_metadata_list) == 0
            assert not 'multisig_txset' in res or len(res.multisig_txset) == 0
            assert not 'unsigned_txset' in res or len(res.unsigned_txset) == 0
            assert len(res.tx_blob_list) == 1
            txes[i][1] = res.tx_blob_list[0]

        daemon = Daemon()
        res = daemon.send_raw_transaction(txes[0][1])
        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

        res = daemon.get_transactions([txes[0][0]])
        assert len(res.txs) >= 1
        tx = [tx for tx in res.txs if tx.tx_hash == txes[0][0]][0]
        assert tx.in_pool
        assert not tx.double_spend_seen

        res = daemon.send_raw_transaction(txes[1][1])
        assert res.not_relayed == False
        assert res.low_mixin == False
        assert res.double_spend == True
        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.too_few_outputs == False

        res = daemon.get_transactions([txes[0][0]])
        assert len(res.txs) >= 1
        tx = [tx for tx in res.txs if tx.tx_hash == txes[0][0]][0]
        assert tx.in_pool
        assert tx.double_spend_seen
Esempio n. 12
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

        daemon.flush_txpool()
        self.check_empty_pool()
Esempio n. 13
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')
        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 = 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
Esempio n. 14
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
Esempio n. 15
0
 def mine(self, address, blocks):
     print("Mining some blocks")
     daemon = Daemon()
     daemon.generateblocks(address, blocks)
Esempio n. 16
0
    def transfer(self):
        daemon = Daemon()

        print("Creating transfer to self")

        dst = {
            'address':
            'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
            '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
        blob_size = len(res.tx_blob) // 2
        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 * blob_size + 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 == 'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq'
        assert e.double_spend_seen == False
        assert not 'confirmations' in e or 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(
            'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
            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 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 == 'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq'
        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':
            'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
            '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':
            'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
            '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 == 'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq'
        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(
            'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
            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 == 'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq'
        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':
            'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
            'amount': 1000000000000
        }
        dst1 = {
            'address':
            'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
            'amount': 1100000000000
        }
        dst2 = {
            'address':
            'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
            '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] -= 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(
            'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
            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 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 == 'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq'
        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 == 'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq'
        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 == 'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq'
        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=
            'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
            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(
            'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
            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(
            'Sumoo1aLd1yKkerxdjbXggMf3mdy5m9tZeWpYU913LSmZuUdMjJnoa67vp2WB7sV2ZHCBZbh2MekDK2emfWCxZZ997WpRfimvjq',
            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
Esempio n. 17
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
Esempio n. 18
0
    def check_reserve_proof(self):
        daemon = Daemon()

        print('Checking reserve proof')

        address0 = '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
        address1 = '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW'

        self.wallet[0].refresh()
        res = self.wallet[0].get_balance()
        balance0 = res.balance
        self.wallet[1].refresh()
        res = self.wallet[1].get_balance()
        balance1 = res.balance

        res = self.wallet[0].get_reserve_proof(all_=True, message='foo')
        assert res.signature.startswith('ReserveProof')
        signature = res.signature
        for i in range(2):
            res = self.wallet[i].check_reserve_proof(address=address0,
                                                     message='foo',
                                                     signature=signature)
            assert res.good
            assert res.total == balance0

            ok = False
            try:
                res = self.wallet[i].check_reserve_proof(address=address0,
                                                         message='bar',
                                                         signature=signature)
            except:
                ok = True
            assert ok or not res.good

            ok = False
            try:
                res = self.wallet[i].check_reserve_proof(address=address1,
                                                         message='foo',
                                                         signature=signature)
            except:
                ok = True
            assert ok or not res.good

        amount = int(balance0 / 10)
        res = self.wallet[0].get_reserve_proof(all_=False,
                                               amount=amount,
                                               message='foo')
        assert res.signature.startswith('ReserveProof')
        signature = res.signature
        for i in range(2):
            res = self.wallet[i].check_reserve_proof(address=address0,
                                                     message='foo',
                                                     signature=signature)
            assert res.good
            assert res.total >= amount and res.total <= balance0

            ok = False
            try:
                res = self.wallet[i].check_reserve_proof(address=address0,
                                                         message='bar',
                                                         signature=signature)
            except:
                ok = True
            assert ok or not res.good

            ok = False
            try:
                res = self.wallet[i].check_reserve_proof(address=address1,
                                                         message='foo',
                                                         signature=signature)
            except:
                ok = True
            assert ok or not res.good

        ok = False
        try:
            self.wallet[0].get_reserve_proof(all_=False,
                                             amount=balance0 + 1,
                                             message='foo')
        except:
            ok = True
        assert ok
Esempio n. 19
0
 def __exit__(self, exc_type, exc_value, traceback):
     daemon = Daemon()
     try:
         daemon.stop_mining()
     except:
         pass
Esempio n. 20
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()
Esempio n. 21
0
 def sweep_dust(self):
     print("Sweeping dust")
     daemon = Daemon()
     self.wallet[0].refresh()
     res = self.wallet[0].sweep_dust()
     assert not 'tx_hash_list' in res or len(res.tx_hash_list) == 0 # there's just one, but it cannot meet the fee
Esempio n. 22
0
    def mine(self, via_daemon):
        print("Test mining via " + ("daemon" if via_daemon else "wallet"))

        daemon = Daemon()
        wallet = Wallet()

        # check info/height/balance before generating blocks
        res_info = daemon.get_info()
        prev_height = res_info.height
        res_getbalance = wallet.get_balance()
        prev_balance = res_getbalance.balance

        res_status = daemon.mining_status()

        if via_daemon:
            res = daemon.start_mining('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', threads_count = 1)
        else:
            res = wallet.start_mining(threads_count = 1)

        res_status = daemon.mining_status()
        assert res_status.active == True
        assert res_status.threads_count == 1
        assert res_status.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
        assert res_status.is_background_mining_enabled == False
        assert res_status.block_reward >= 600000000000

        # wait till we mined a few of them
        target_height = prev_height + 5
        height = prev_height
        timeout = 240 # randomx is slow to init
        while height < target_height:
            seen_height = height
            for _ in range(timeout):
                time.sleep(1)
                height = daemon.get_info().height
                if height > seen_height:
                    break
            else:
                assert False, 'Failed to mine successor to block %d (initial block = %d)' % (seen_height, prev_height)
            timeout = 10

        if via_daemon:
            res = daemon.stop_mining()
        else:
            res = wallet.stop_mining()

        res_status = daemon.mining_status()
        assert res_status.active == False

        res_info = daemon.get_info()
        new_height = res_info.height

        wallet.refresh()
        res_getbalance = wallet.get_balance()
        balance = res_getbalance.balance
        assert balance >= prev_balance + (new_height - prev_height) * 600000000000

        if via_daemon:
            res = daemon.start_mining('42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm', threads_count = 1, do_background_mining = True)
        else:
            res = wallet.start_mining(threads_count = 1, do_background_mining = True)
        res_status = daemon.mining_status()
        assert res_status.active == True
        assert res_status.threads_count == 1
        assert res_status.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
        assert res_status.is_background_mining_enabled == True
        assert res_status.block_reward >= 600000000000

        # don't wait, might be a while if the machine is busy, which it probably is
        if via_daemon:
            res = daemon.stop_mining()
        else:
            res = wallet.stop_mining()
        res_status = daemon.mining_status()
        assert res_status.active == False
Esempio n. 23
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, 16) == (res_info.cumulative_difficulty_top64 << 64) + res_info.cumulative_difficulty
        cumulative_difficulty = int(res_info.wide_cumulative_difficulty, 16)

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

        res = daemon.get_fee_estimate()
        assert res.fee == 1200000
        assert res.quantization_mask == 10000
        res = daemon.get_fee_estimate(10)
        assert res.fee <= 1200000

        # 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 = height + n))
            block_header = res_getblock[n].block_header
            assert abs(block_header.timestamp - time.time()) < 60 # within 60 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, 16) == (block_header.difficulty_top64 << 64) + block_header.difficulty
            assert int(block_header.wide_cumulative_difficulty, 16) == (block_header.cumulative_difficulty_top64 << 64) + block_header.cumulative_difficulty
            assert block_header.reward >= 600000000000 # tail emission
            cumulative_difficulty += int(block_header.wide_difficulty, 16)
            assert cumulative_difficulty == int(block_header.wide_cumulative_difficulty, 16)
            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 = 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, 16) == (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 = 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
            assert res_sum.emission_amount_top64 == 0
            assert res_sum.emission_amount == int(res_sum.wide_emission_amount, 16)
            assert res_sum.fee_amount == int(res_sum.wide_fee_amount, 16)

        res = daemon.get_coinbase_tx_sum(0, 1)
        assert res.emission_amount == 17592186044415
        assert res.emission_amount_top64 == 0
        assert res.fee_amount == 0
        assert res.fee_amount_top64 == 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

        res = daemon.get_fee_estimate()
        assert res.fee == 1200000
        assert res.quantization_mask == 10000
        res = daemon.get_fee_estimate(10)
        assert res.fee <= 1200000
    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
Esempio n. 25
0
 def reset(self):
     print('Resetting blockchain')
     daemon = Daemon()
     daemon.pop_blocks(1000)
     daemon.flush_txpool()
Esempio n. 26
0
    def check_double_spend_detection(self):
        print('Checking double spend detection')
        txes = [[None, None], [None, None]]
        for i in range(2):
            self.wallet[0].restore_deterministic_wallet(
                seed=
                'velvet lymph giddy number token physics poetry unquoted nibs useful sabotage limits benches lifestyle eden nitrogen anvil fewest avoid batch vials washing fences goat unquoted'
            )
            self.wallet[0].refresh()
            res = self.wallet[0].get_balance()
            unlocked_balance = res.unlocked_balance
            res = self.wallet[0].sweep_all(
                address=
                '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW',
                do_not_relay=True,
                get_tx_hex=True)
            assert len(res.tx_hash_list) == 1
            assert len(res.tx_hash_list[0]) == 32 * 2
            txes[i][0] = res.tx_hash_list[0]
            assert len(res.fee_list) == 1
            assert res.fee_list[0] > 0
            assert len(res.amount_list) == 1
            assert res.amount_list[0] == unlocked_balance - res.fee_list[0]
            assert len(res.tx_blob_list) > 0
            assert len(res.tx_blob_list[0]) > 0
            assert not 'tx_metadata_list' in res or len(
                res.tx_metadata_list) == 0
            assert not 'multisig_txset' in res or len(res.multisig_txset) == 0
            assert not 'unsigned_txset' in res or len(res.unsigned_txset) == 0
            assert len(res.tx_blob_list) == 1
            txes[i][1] = res.tx_blob_list[0]

        daemon = Daemon()
        res = daemon.send_raw_transaction(txes[0][1])
        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

        res = daemon.get_transactions([txes[0][0]])
        assert len(res.txs) >= 1
        tx = [tx for tx in res.txs if tx.tx_hash == txes[0][0]][0]
        assert tx.in_pool
        assert not tx.double_spend_seen

        res = daemon.send_raw_transaction(txes[1][1])
        assert res.not_relayed == False
        assert res.low_mixin == False
        assert res.double_spend == True
        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

        res = daemon.get_transactions([txes[0][0]])
        assert len(res.txs) >= 1
        tx = [tx for tx in res.txs if tx.tx_hash == txes[0][0]][0]
        assert tx.in_pool
        assert tx.double_spend_seen
Esempio n. 27
0
 def reset(self):
     print('Resetting blockchain')
     daemon = Daemon()
     res = daemon.get_height()
     daemon.pop_blocks(res.height - 1)
     daemon.flush_txpool()
Esempio n. 28
0
    def check_tx_proof(self, txid, amount):
        daemon = Daemon()

        print('Checking tx proof')

        self.wallet[0].refresh()
        self.wallet[1].refresh()

        sending_address = '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
        receiving_address = '44Kbx4sJ7JDRDV5aAhLJzQCjDz2ViLRduE3ijDZu3osWKBjMGkV1XPk4pfDUMqt1Aiezvephdqm6YD19GKFD9ZcXVUTp6BW'
        res = self.wallet[0].get_tx_proof(txid, sending_address, 'foo');
        assert res.signature.startswith('InProof');
        signature0i = res.signature
        res = self.wallet[0].get_tx_proof(txid, receiving_address, 'bar');
        assert res.signature.startswith('OutProof');
        signature0o = res.signature
        res = self.wallet[1].get_tx_proof(txid, receiving_address, 'baz');
        assert res.signature.startswith('InProof');
        signature1 = res.signature

        res = self.wallet[0].check_tx_proof(txid, sending_address, 'foo', signature0i);
        assert res.good
        assert res.received > 0 # likely change
        assert not res.in_pool
        assert res.confirmations == 1

        ok = False
        try: res = self.wallet[0].check_tx_proof('0' * 64, sending_address, 'foo', signature0i);
        except: ok = True
        assert ok or not res.good

        ok = False
        try: res = self.wallet[0].check_tx_proof(txid, receiving_address, 'foo', signature0i);
        except: ok = True
        assert ok or not res.good

        ok = False
        try: res = self.wallet[0].check_tx_proof(txid, sending_address, '', signature0i);
        except: ok = True
        assert ok or not res.good

        ok = False
        try: res = self.wallet[0].check_tx_proof(txid, sending_address, 'foo', signature1);
        except: ok = True
        assert ok or not res.good


        res = self.wallet[0].check_tx_proof(txid, receiving_address, 'bar', signature0o);
        assert res.good
        assert res.received == amount
        assert not res.in_pool
        assert res.confirmations == 1

        ok = False
        try: res = self.wallet[0].check_tx_proof('0' * 64, receiving_address, 'bar', signature0o);
        except: ok = True
        assert ok or not res.good

        ok = False
        try: res = self.wallet[0].check_tx_proof(txid, sending_address, 'bar', signature0o);
        except: ok = True
        assert ok or not res.good

        ok = False
        try: res = self.wallet[0].check_tx_proof(txid, receiving_address, '', signature0o);
        except: ok = True
        assert ok or not res.good

        ok = False
        try: res = self.wallet[0].check_tx_proof(txid, receiving_address, 'bar', signature0i);
        except: ok = True
        assert ok or not res.good


        res = self.wallet[1].check_tx_proof(txid, receiving_address, 'baz', signature1);
        assert res.good
        assert res.received == amount
        assert not res.in_pool
        assert res.confirmations == 1

        ok = False
        try: res = self.wallet[1].check_tx_proof('0' * 64, receiving_address, 'baz', signature1);
        except: ok = True
        assert ok or not res.good

        ok = False
        try: res = self.wallet[1].check_tx_proof(txid, sending_address, 'baz', signature1);
        except: ok = True
        assert ok or not res.good

        ok = False
        try: res = self.wallet[1].check_tx_proof(txid, receiving_address, '', signature1);
        except: ok = True
        assert ok or not res.good

        ok = False
        try: res = self.wallet[1].check_tx_proof(txid, receiving_address, 'baz', signature0o);
        except: ok = True
        assert ok or not res.good
Esempio n. 29
0
    def mine(self):
        print "Test mining"

        daemon = Daemon()
        wallet = Wallet()

        # check info/height/balance before generating blocks
        res_info = daemon.get_info()
        prev_height = res_info.height
        res_getbalance = wallet.get_balance()
        prev_balance = res_getbalance.balance

        res_status = daemon.mining_status()

        res = daemon.start_mining(
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
            threads_count=1)

        res_status = daemon.mining_status()
        assert res_status.active == True
        assert res_status.threads_count == 1
        assert res_status.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
        assert res_status.is_background_mining_enabled == False
        assert res_status.block_reward >= 600000000000

        # wait till we mined a few of them
        timeout = 5
        timeout_height = prev_height
        while True:
            time.sleep(1)
            res_info = daemon.get_info()
            height = res_info.height
            if height >= prev_height + 5:
                break
            if height > timeout_height:
                timeout = 5
                timeout_height = height
            else:
                timeout -= 1
            assert timeout >= 0

        res = daemon.stop_mining()
        res_status = daemon.mining_status()
        assert res_status.active == False

        res_info = daemon.get_info()
        new_height = res_info.height

        wallet.refresh()
        res_getbalance = wallet.get_balance()
        balance = res_getbalance.balance
        assert balance >= prev_balance + (new_height -
                                          prev_height) * 600000000000

        res = daemon.start_mining(
            '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm',
            threads_count=1,
            do_background_mining=True)
        res_status = daemon.mining_status()
        assert res_status.active == True
        assert res_status.threads_count == 1
        assert res_status.address == '42ey1afDFnn4886T7196doS9GPMzexD9gXpsZJDwVjeRVdFCSoHnv7KPbBeGpzJBzHRCAs9UxqeoyFQMYbqSWYTfJJQAWDm'
        assert res_status.is_background_mining_enabled == True
        assert res_status.block_reward >= 600000000000

        # don't wait, might be a while if the machine is busy, which it probably is
        res = daemon.stop_mining()
        res_status = daemon.mining_status()
        assert res_status.active == False
Esempio n. 30
0
    def test_access_mining(self):
        print('Testing access mining')
        daemon = Daemon(idx=1)
        wallet = Wallet(idx=3)

        res = daemon.rpc_access_info(client=self.get_signature())
        assert len(res.hashing_blob) > 39
        assert res.height == 1
        assert res.top_hash == '418015bb9ae982a1975da7d79277c2705727a56894ba0fb246adaabb1f4632e3'
        assert res.credits_per_hash_found == 5000
        assert res.diff == 10
        assert res.credits == 0
        cookie = res.cookie

        # Try random nonces till we find one that's valid and one that's invalid
        nonce = 0
        found_valid = 0
        found_invalid = 0
        last_credits = 0
        while found_valid == 0 or found_invalid == 0:
            nonce += 1
            try:
                res = daemon.rpc_access_submit_nonce(
                    nonce=nonce, cookie=cookie, client=self.get_signature())
                found_valid += 1
                assert res.credits == last_credits + 5000
            except Exception as e:
                found_invalid += 1
                res = daemon.rpc_access_info(client=self.get_signature())
                assert res.credits < last_credits or res.credits == 0
            assert nonce < 1000  # can't find both valid and invalid -> the RPC probably fails
            last_credits = res.credits

        # we should now have 1 valid nonce, and a number of bad ones
        res = daemon.rpc_access_info(client=self.get_signature())
        assert len(res.hashing_blob) > 39
        assert res.height > 1
        assert res.top_hash != '418015bb9ae982a1975da7d79277c2705727a56894ba0fb246adaabb1f4632e3'  # here, any share matches network diff
        assert res.credits_per_hash_found == 5000
        assert res.diff == 10
        cookie = res.cookie

        res = daemon.rpc_access_data()
        assert len(res.entries) > 0
        e = [x for x in res.entries if x['client'] == self.public_key]
        assert len(e) == 1
        e = e[0]
        assert e.nonces_stale == 0
        assert e.nonces_bad == found_invalid
        assert e.nonces_good == found_valid
        assert e.nonces_dupe == 0

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

        # we should now have at least 5000
        res = daemon.rpc_access_info(client=self.get_signature())
        assert res.credits == last_credits
        assert res.credits >= 5000  # last one was a valid nonce

        res = daemon.rpc_access_data()
        assert len(res.entries) > 0
        e = [x for x in res.entries if x['client'] == self.public_key]
        assert len(e) == 1
        e = e[0]
        assert e.nonces_stale == 0
        assert e.nonces_bad == found_invalid
        assert e.nonces_good == found_valid
        assert e.nonces_dupe == 0
        assert e.balance == 5000
        assert e.credits_total >= 5000

        # find a valid one, then check dupes aren't allowed
        res = daemon.rpc_access_info(client=self.get_signature())
        cookie = res.cookie
        old_cookie = cookie  # we keep that so can submit a stale later
        while True:
            nonce += 1
            try:
                res = daemon.rpc_access_submit_nonce(
                    nonce=nonce, cookie=cookie, client=self.get_signature())
                found_valid += 1
                break
            except:
                found_invalid += 1
            assert nonce < 1000  # can't find both valid and invalid -> the RPC probably fails

        res = daemon.rpc_access_data()
        assert len(res.entries) > 0
        e = [x for x in res.entries if x['client'] == self.public_key]
        assert len(e) == 1
        e = e[0]
        assert e.nonces_stale == 0
        assert e.nonces_bad == found_invalid
        assert e.nonces_good == found_valid
        assert e.nonces_dupe == 0

        ok = False
        try:
            res = daemon.rpc_access_submit_nonce(nonce=nonce,
                                                 cookie=cookie,
                                                 client=self.get_signature())
        except:
            ok = True
        assert ok

        res = daemon.rpc_access_data()
        assert len(res.entries) > 0
        e = [x for x in res.entries if x['client'] == self.public_key]
        assert len(e) == 1
        e = e[0]
        assert e.nonces_stale == 0
        assert e.nonces_bad == found_invalid
        assert e.nonces_good == found_valid
        assert e.nonces_dupe == 1

        # find stales without updating cookie, one within 5 seconds (accepted), one later (rejected)
        res = daemon.rpc_access_info(client=self.get_signature())
        found_close_stale = 0
        found_late_stale = 0
        while found_close_stale == 0 or found_late_stale == 0:
            nonce += 1
            try:
                res = daemon.rpc_access_submit_nonce(
                    nonce=nonce, cookie=cookie, client=self.get_signature())
                found_close_stale += 1
                found_valid += 1
            except Exception as e:
                #if e[0]['error']['code'] == -18: # stale
                if "'code': -18" in str(
                        e
                ):  # stale (ugly version, but also works with python 3)
                    found_late_stale += 1
                else:
                    found_invalid += 1
            assert nonce < 1000  # can't find both valid and invalid -> the RPC probably fails

        res = daemon.rpc_access_data()
        assert len(res.entries) > 0
        e = [x for x in res.entries if x['client'] == self.public_key]
        assert len(e) == 1
        e = e[0]
        assert e.nonces_stale == found_late_stale  # close stales are accepted, don't count here
        assert e.nonces_bad == found_invalid
        assert e.nonces_good == found_valid
        assert e.nonces_dupe == 1

        # find very stale with old cookie (rejected)
        res = daemon.rpc_access_info(client=self.get_signature())
        nonce += 1
        ok = False
        try:
            res = daemon.rpc_access_submit_nonce(nonce=nonce,
                                                 cookie=old_cookie,
                                                 client=self.get_signature())
        except:
            found_late_stale += 1
            ok = True
        assert ok

        res = daemon.rpc_access_data()
        assert len(res.entries) > 0
        e = [x for x in res.entries if x['client'] == self.public_key]
        assert len(e) == 1
        e = e[0]
        assert e.nonces_stale == found_late_stale
        assert e.nonces_bad == found_invalid
        assert e.nonces_good == found_valid
        assert e.nonces_dupe == 1