def deck_parser(args: Tuple[Provider, dict, int, str], prod: bool = True) -> Optional[Deck]: '''deck parser function''' provider = args[0] raw_tx = args[1] deck_version = args[2] p2th = args[3] try: validate_deckspawn_p2th(provider, raw_tx, p2th) d = parse_deckspawn_metainfo(read_tx_opreturn(raw_tx), deck_version) if d: d["id"] = raw_tx["txid"] try: d["time"] = raw_tx["blocktime"] except KeyError: d["time"] = 0 d["issuer"] = find_tx_sender(provider, raw_tx) d["network"] = provider.network d["production"] = prod d["tx_confirmations"] = raw_tx["confirmations"] return Deck(**d) except (InvalidDeckSpawn, InvalidDeckMetainfo, InvalidDeckVersion, InvalidNulldataOutput) as err: pass return None
def find_vote_casts(provider, vote: Vote, choice_index: int): '''find and verify vote_casts on this vote_choice_address''' vote_casts = provider.listtransactions( vote.vote_choice_address[choice_index]) for tx in vote_casts: raw_tx = provider.getrawtransaction(tx, 1) sender = find_tx_sender(provider, raw_tx) confirmations = raw_tx["confirmations"] blocknum = provider.getblock(raw_tx["blockhash"])["height"] yield VoteCast(vote, sender, blocknum, confirmations, raw_tx["blocktime"])
def find_vote_inits(provider: Provider, deck: Deck) -> Iterable[Vote]: '''find vote_inits on this deck''' vote_ints = provider.listtransactions(deck_vote_tag(deck)) for txid in vote_ints: try: raw_vote = provider.getrawtransaction(txid) vote = parse_vote_info(read_tx_opreturn(raw_vote)) vote["vote_id"] = txid vote["sender"] = find_tx_sender(provider, raw_vote) vote["deck"] = deck yield Vote(**vote) except AssertionError: pass
def card_bundler(provider: Provider, deck: Deck, tx: dict) -> CardBundle: '''each blockchain transaction can contain multiple cards, wrapped in bundles. This method finds and returns those bundles.''' return CardBundle(deck=deck, blockhash=tx['blockhash'], txid=tx['txid'], timestamp=tx['time'], blockseq=tx_serialization_order(provider, tx["blockhash"], tx["txid"]), blocknum=provider.getblock(tx["blockhash"])["height"], sender=find_tx_sender(provider, tx), vouts=tx['vout'], tx_confirmations=tx['confirmations'])
def card_parser(args: Tuple[Provider, Deck, dict]) -> list: '''this function wraps all the card transfer parsing''' provider = args[0] deck = args[1] raw_tx = args[2] try: validate_card_transfer_p2th(deck, raw_tx) # validate P2TH first card_metainfo = parse_card_transfer_metainfo( read_tx_opreturn(raw_tx), deck.version) vouts = raw_tx["vout"] sender = find_tx_sender(provider, raw_tx) try: # try to get block seq number blockseq = tx_serialization_order(provider, raw_tx["blockhash"], raw_tx["txid"]) except KeyError: blockseq = 0 try: # try to get block number of block when this tx was written blocknum = provider.getblock(raw_tx["blockhash"])["height"] except KeyError: blocknum = 0 try: # try to get tx confirmation count tx_confirmations = raw_tx["confirmations"] except KeyError: tx_confirmations = 0 cards = postprocess_card(card_metainfo, raw_tx, sender, vouts, blockseq, blocknum, tx_confirmations, deck) cards = [CardTransfer(**card) for card in cards] except (InvalidCardTransferP2TH, CardVersionMismatch, CardNumberOfDecimalsMismatch, InvalidVoutOrder, RecieverAmountMismatch, DecodeError, TypeError, InvalidNulldataOutput) as e: return [] return cards
def find_card_bundles(provider: Provider, deck: Deck) -> Optional[Iterator]: '''each blockchain transaction can contain multiple cards, wrapped in bundles. This method finds and returns those bundles.''' if isinstance(provider, RpcNode): if deck.id is None: raise Exception("deck.id required to listtransactions") batch_data = [('getrawtransaction', [i["txid"], 1]) for i in provider.listtransactions(deck.id)] result = provider.batch(batch_data) if result is not None: raw_txns = [i['result'] for i in result if result] else: raise EmptyP2THDirectory({'error': 'No cards found on this deck.'}) else: if deck.p2th_address is None: raise Exception("deck.p2th_address required to listtransactions") try: raw_txns = (provider.getrawtransaction(i, 1) for i in provider.listtransactions(deck.p2th_address)) except TypeError: raise EmptyP2THDirectory({'error': 'No cards found on this deck.'}) return (CardBundle(deck=deck, blockhash=i['blockhash'], txid=i['txid'], timestamp=i['time'], blockseq=tx_serialization_order(provider, i["blockhash"], i["txid"]), blocknum=provider.getblock(i["blockhash"])["height"], sender=find_tx_sender(provider, i), vouts=i['vout'], tx_confirmations=i['confirmations'] ) for i in raw_txns)