Exemplo n.º 1
0
 def test_valid_address(self):
     """Test address validation"""
     # Null should always be false
     self.assertFalse(Validators.is_valid_address(None))
     os.environ['BANANO'] = '1'
     # Valid
     self.assertTrue(
         Validators.is_valid_address(
             'ban_1bananobh5rat99qfgt1ptpieie5swmoth87thi74qgbfrij7dcgjiij94xr'
         ))
     # Bad checksum
     self.assertFalse(
         Validators.is_valid_address(
             'ban_1bananobh5rat99qfgt1ptpieie5swmoth87thi74qgbfrij7dcgjiij94xa'
         ))
     # Bad length
     self.assertFalse(
         Validators.is_valid_address(
             'ban_1bananobh5rat99qfgt1ptpieie5swmoth87thi74qgbfrij7dcgjiij94x'
         ))
     del os.environ['BANANO']
     # Valid
     self.assertTrue(
         Validators.is_valid_address(
             'nano_1bananobh5rat99qfgt1ptpieie5swmoth87thi74qgbfrij7dcgjiij94xr'
         ))
     # Bad checksum
     self.assertFalse(
         Validators.is_valid_address(
             'nano_1bananobh5rat99qfgt1ptpieie5swmoth87thi74qgbfrij7dcgjiij94xa'
         ))
     # Bad length
     self.assertFalse(
         Validators.is_valid_address(
             'nano_1bananobh5rat99qfgt1ptpieie5swmoth87thi74qgbfrij7dcgjiij94x'
         ))
     # Valid
     self.assertTrue(
         Validators.is_valid_address(
             'xrb_1bananobh5rat99qfgt1ptpieie5swmoth87thi74qgbfrij7dcgjiij94xr'
         ))
     # Bad checksum
     self.assertFalse(
         Validators.is_valid_address(
             'xrb_1bananobh5rat99qfgt1ptpieie5swmoth87thi74qgbfrij7dcgjiij94xa'
         ))
     # Bad length
     self.assertFalse(
         Validators.is_valid_address(
             'xrb_1bananobh5rat99qfgt1ptpieie5swmoth87thi74qgbfrij7dcgjiij94x'
         ))
Exemplo n.º 2
0
    async def send(self, request: web.Request, request_json: dict):
        """RPC send"""
        if 'wallet' not in request_json or 'source' not in request_json or 'destination' not in request_json or 'amount' not in request_json:
            return self.generic_error()
        elif not Validators.is_valid_address(request_json['source']):
            return self.json_response(data={'error': 'Invalid source'})
        elif not Validators.is_valid_address(request_json['destination']):
            return self.json_response(data={'error': 'Invalid destination'})

        id = request_json['id'] if 'id' in request_json else None
        work = request_json['work'] if 'work' in request_json else None

        # Retrieve wallet
        try:
            wallet = await Wallet.get_wallet(request_json['wallet'])
        except WalletNotFound:
            return self.json_response(data={'error': 'wallet not found'})
        except WalletLocked:
            return self.json_response(data={'error': 'wallet locked'})

        # Retrieve account on wallet
        account = await wallet.get_account(request_json['source'])
        if account is None:
            return self.json_response(data={'error': 'Account not found'})

        # Try to create and publish send block
        wallet = WalletUtil(account, wallet)
        try:
            resp = await wallet.send(int(request_json['amount']),
                                     request_json['destination'],
                                     id=id,
                                     work=work)
        except AccountNotFound:
            return self.json_response(data={'error': 'Account not found'})
        except BlockNotFound:
            return self.json_response(data={'error': 'Block not found'})
        except WorkFailed:
            return self.json_response(
                data={'error': 'Failed to generate work'})
        except ProcessFailed:
            return self.json_response(data={'error': 'RPC Process failed'})
        except InsufficientBalance:
            return self.json_response(data={'error': 'insufficient balance'})

        if resp is None:
            return self.json_response(
                data={'error': 'Unable to create send block'})

        return self.json_response(data=resp)
Exemplo n.º 3
0
    async def wallet_representative_set(self, request: web.Request,
                                        request_json: dict):
        """RPC wallet_representative_set"""
        if 'wallet' not in request_json or 'representative' not in request_json or (
                'update_existing_accounts' in request_json and not isinstance(
                    request_json['update_existing_accounts'], bool)):
            return self.generic_error()
        elif not Validators.is_valid_address(request_json['representative']):
            return self.json_response(data={'error': 'Invalid address'})

        update_existing = False
        if 'update_existing_accounts' in request_json:
            update_existing = request_json['update_existing_accounts']

        # Retrieve wallet
        try:
            wallet = await Wallet.get_wallet(request_json['wallet'])
        except WalletNotFound:
            return self.json_response(data={'error': 'wallet not found'})
        except WalletLocked:
            return self.json_response(data={'error': 'wallet locked'})

        wallet.representative = request_json['representative']
        await wallet.save(update_fields=['representative'])

        if update_existing:
            await wallet.bulk_representative_update(
                request_json['representative'])

        return self.json_response(data={'set': '1'})
Exemplo n.º 4
0
async def wallet_representative_set(wallet_id: str, rep: str, update_existing: bool = False):
    # Retrieve wallet
    # Retrieve wallet
    crypt = None
    password=None
    if not Validators.is_valid_address(rep):
        print("Invalid representative")
        exit(1)
    try:
        wallet = await Wallet.get_wallet(wallet_id)
    except WalletNotFound:
        print(f"No wallet found with ID: {wallet_id}")
        exit(1)
    except WalletLocked as wl:
        wallet = wl.wallet
        if update_existing:
            while True:
                try:
                    npass = getpass.getpass(prompt='Enter current password to decrypt wallet:')
                    crypt = AESCrypt(npass)
                    try:
                        decrypted = crypt.decrypt(wl.wallet.seed)
                        wallet = wl.wallet
                        wallet.seed = decrypted
                        password=npass
                    except DecryptionError:
                        print("**Invalid password**")
                except KeyboardInterrupt:
                    break
                    exit(0)

    wallet.representative = rep
    await wallet.save(update_fields=['representative'])
    await wallet.bulk_representative_update(rep)
    print(f"Representative changed")
Exemplo n.º 5
0
    async def account_representative_set(self, request: web.Request,
                                         request_json: dict):
        """RPC account_representative_set"""
        if 'wallet' not in request_json or 'account' not in request_json or 'representative' not in request_json:
            return self.generic_error()
        elif not Validators.is_valid_address(request_json['account']):
            return self.json_response(data={'error': 'Invalid account'})
        elif not Validators.is_valid_address(request_json['representative']):
            return self.json_response(data={'error': 'Invalid representative'})

        work = request_json['work'] if 'work' in request_json else None

        # Retrieve wallet
        try:
            wallet = await Wallet.get_wallet(request_json['wallet'])
        except WalletNotFound:
            return self.json_response(data={'error': 'wallet not found'})
        except WalletLocked:
            return self.json_response(data={'error': 'wallet locked'})

        # Retrieve account on wallet
        account = await wallet.get_account(request_json['account'])
        if account is None:
            return self.json_response(data={'error': 'Account not found'})

        # Try to create and publish CHANGE block
        wallet = WalletUtil(account, wallet)
        try:
            resp = await wallet.representative_set(
                request_json['representative'], work=work)
        except AccountNotFound:
            return self.json_response(data={'error': 'Account not found'})
        except WorkFailed:
            return self.json_response(
                data={'error': 'Failed to generate work'})
        except ProcessFailed:
            return self.json_response(data={'error': 'RPC Process failed'})

        if resp is None:
            return self.json_response(
                data={'error': 'Unable to create change block'})

        return self.json_response(data=resp)
Exemplo n.º 6
0
    async def wallet_contains(self, request: web.Request, request_json: dict):
        """RPC wallet_contains"""
        if 'wallet' not in request_json or 'account' not in request_json:
            return self.generic_error()
        elif not Validators.is_valid_address(request_json['account']):
            return self.json_response(data={'error': 'Invalid account'})

        # Retrieve wallet
        try:
            wallet = await Wallet.get_wallet(request_json['wallet'])
        except WalletNotFound:
            return self.json_response(data={'error': 'wallet not found'})
        except WalletLocked:
            return self.json_response(data={'error': 'wallet locked'})

        exists = (await
                  wallet.get_account(request_json['account'])) is not None

        return self.json_response(data={'exists': '1' if exists else '0'})
Exemplo n.º 7
0
    async def receive(self, request: web.Request, request_json: dict):
        """RPC receive"""
        if 'wallet' not in request_json or 'account' not in request_json or 'block' not in request_json:
            return self.generic_error()
        elif not Validators.is_valid_address(request_json['account']):
            return self.json_response(data={'error': 'Invalid address'})
        elif not Validators.is_valid_block_hash(request_json['block']):
            return self.json_response(data={'error': 'Invalid block'})

        work = request_json['work'] if 'work' in request_json else None

        # Retrieve wallet
        try:
            wallet = await Wallet.get_wallet(request_json['wallet'])
        except WalletNotFound:
            return self.json_response(data={'error': 'wallet not found'})
        except WalletLocked:
            return self.json_response(data={'error': 'wallet locked'})

        # Retrieve account on wallet
        account = await wallet.get_account(request_json['account'])
        if account is None:
            return self.json_response(data={'error': 'Account not found'})

        # Try to receive block
        wallet = WalletUtil(account, wallet)
        try:
            response = await wallet.receive(request_json['block'], work=work)
        except BlockNotFound:
            return self.json_response(data={'error': 'Block not found'})
        except WorkFailed:
            return self.json_response(
                data={'error': 'Failed to generate work'})
        except ProcessFailed:
            return self.json_response(data={'error': 'RPC Process failed'})

        if response is None:
            return self.json_response(
                data={'error': 'Unable to receive block'})

        return self.json_response(data=response)
Exemplo n.º 8
0
    def instance(cls) -> 'Config':
        if cls._instance is None:
            cls._instance = cls.__new__(cls)
            try:
                with open(f"{Utils.get_project_root().joinpath(pathlib.PurePath('config.yaml'))}", "r") as in_yaml:
                    cls.yaml = list(yaml.load_all(in_yaml, Loader=yaml.FullLoader))[0]
            except FileNotFoundError:
                cls.yaml = None
            # Parse options
            cls.banano = cls.get_yaml_property('wallet', 'banano', False)
            cls.log_file = cls.get_yaml_property('server', 'log_file', default='/tmp/pippin_wallet.log')
            cls.debug = cls.get_yaml_property('server', 'debug', default=False)
            cls.stdout = cls.get_yaml_property('server', 'log_to_stdout', default=False)
            cls.node_url = cls.get_yaml_property('server', 'node_rpc_url', default='http://[::1]:7072' if cls.banano else 'http://[::1]:7076')
            cls.node_ws_url = cls.get_yaml_property('server', 'node_ws_url', None)
            cls.port = cls.get_yaml_property('server', 'port', default=11338)
            cls.host = cls.get_yaml_property('server', 'host', default='127.0.0.1')
            cls.work_peers = cls.get_yaml_property('wallet', 'work_peers', [])
            cls.node_work_generate = cls.get_yaml_property('wallet', 'node_work_generate', False)
            cls.receive_minimum = cls.get_yaml_property('wallet', 'receive_minimum', 1000000000000000000000000000 if cls.banano else 1000000000000000000000000)
            cls.auto_receive_on_send = cls.get_yaml_property('wallet', 'auto_receive_on_send', True)
            cls.max_work_processes = cls.get_yaml_property('wallet', 'max_work_processes', 1)
            cls.max_sign_threads = cls.get_yaml_property('wallet', 'max_sign_threads', 1)
            if not cls.banano:
                cls.preconfigured_reps = cls.get_yaml_property('wallet', 'preconfigured_representatives_nano', default=None)
            else:
                cls.preconfigured_reps = cls.get_yaml_property('wallet', 'preconfigured_representatives_banano', default=None)
            # Enforce that all reps are valid
            if cls.preconfigured_reps is not None:
                cls.preconfigured_reps = set(cls.preconfigured_reps)
                for r in cls.preconfigured_reps:
                    if not Validators.is_valid_address(r):
                        log.server_logger.warn(f"{r} is not a valid representative!")
                        cls.preconfigured_reps.remove(r)
                if len(cls.preconfigured_reps) == 0:
                    cls.preconfigured_reps = None
            # Go to default if None
            if cls.preconfigured_reps is None:
                cls.preconfigured_reps = DEFAULT_BANANO_REPS if cls.banano else DEFAULT_NANO_REPS

        return cls._instance