import asyncio import logging from binascii import unhexlify from torba.client.baseledger import BaseLedger from lbrynet.schema.uri import parse_lbry_uri, URIParseError from lbrynet.wallet.dewies import dewies_to_lbc from lbrynet.wallet.resolve import Resolver from lbrynet.wallet.account import Account, validate_claim_id from lbrynet.wallet.network import Network from lbrynet.wallet.database import WalletDatabase from lbrynet.wallet.transaction import Transaction from lbrynet.wallet.header import Headers, UnvalidatedHeaders log = logging.getLogger(__name__) class MainNetLedger(BaseLedger): name = 'LBRY Credits' symbol = 'LBC' network_name = 'mainnet' headers: Headers account_class = Account database_class = WalletDatabase headers_class = Headers network_class = Network transaction_class = Transaction secret_prefix = bytes((0x1c,)) pubkey_address_prefix = bytes((0x55,)) script_address_prefix = bytes((0x7a,)) extended_public_key_prefix = unhexlify('0488b21e') extended_private_key_prefix = unhexlify('0488ade4') max_target = 0x0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff genesis_hash = '9c89283ba0f3227f6c03b70216b9f665f0118d5e0fa729cedf4fb34d6a34f463' genesis_bits = 0x1f00ffff target_timespan = 150 default_fee_per_byte = 50 default_fee_per_name_char = 200000 def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fee_per_name_char = self.config.get('fee_per_name_char', self.default_fee_per_name_char) @property def resolver(self): return Resolver(self.headers.claim_trie_root, self.headers.height, self.transaction_class, hash160_to_address=self.hash160_to_address, network=self.network, ledger=self) async def resolve(self, page, page_size, *uris): for uri in uris: try: parsed_uri = parse_lbry_uri(uri) if parsed_uri.claim_id: validate_claim_id(parsed_uri.claim_id) except URIParseError as err: return {'error': err.args[0]} except Exception as e: return {'error': str(e)} try: resolver = self.resolver resolutions = await self.network.get_values_for_uris(self.headers.hash().decode(), *uris) return await resolver._handle_resolutions(resolutions, uris, page, page_size) except Exception as e: log.exception(e) return {'error': str(e)} async def get_claim_by_claim_id(self, claim_id): result = (await self.network.get_claims_by_ids(claim_id)).pop(claim_id, {}) return await self.resolver.get_certificate_and_validate_result(result) async def get_claim_by_outpoint(self, txid, nout): claims = (await self.network.get_claims_in_tx(txid)) or [] for claim in claims: if claim['nout'] == nout: return await self.resolver.get_certificate_and_validate_result(claim) return 'claim not found' async def start(self): await super().start() await asyncio.gather(*(a.maybe_migrate_certificates() for a in self.accounts)) await asyncio.gather(*(a.save_max_gap() for a in self.accounts)) await self._report_state() async def _report_state(self): for account in self.accounts: total_receiving = len((await account.receiving.get_addresses())) total_change = len((await account.change.get_addresses())) channel_count = await account.get_channel_count() claim_count = await account.get_claim_count() balance = dewies_to_lbc(await account.get_balance()) log.info("Loaded account %s with %s LBC, %d receiving addresses (gap: %d), " "%d change addresses (gap: %d), %d channels, %d certificates and %d claims. ", account.id, balance, total_receiving, account.receiving.gap, total_change, account.change.gap, channel_count, len(account.certificates), claim_count) class TestNetLedger(MainNetLedger): network_name = 'testnet' pubkey_address_prefix = bytes((111,)) script_address_prefix = bytes((196,)) extended_public_key_prefix = unhexlify('043587cf') extended_private_key_prefix = unhexlify('04358394') class RegTestLedger(MainNetLedger): network_name = 'regtest' headers_class = UnvalidatedHeaders pubkey_address_prefix = bytes((111,)) script_address_prefix = bytes((196,)) extended_public_key_prefix = unhexlify('043587cf') extended_private_key_prefix = unhexlify('04358394') max_target = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff genesis_hash = '6e3fcf1299d4ec5d79c3a4c91d624a4acf9e2e173d95a1a0504f677669687556' genesis_bits = 0x207fffff target_timespan = 1