Beispiel #1
0
 def __init__(self,mongodbutil):
     self.itemArray = []
     self.mongodbutil = mongodbutil
     originalBloom = self.readBloomValueFromFile()
     if originalBloom == '' :
         self.bloomFilter = BloomFilter()
     else:
         #self.bloomFilter = BloomFilter(int.from_bytes(originalBloom, byteorder='big'))
         self.bloomFilter = BloomFilter(int(originalBloom))
     self.urlExist = False
Beispiel #2
0
def test_casting_to_integer():
    bloom = BloomFilter()

    assert int(bloom) == 0

    bloom.add(b'value 1')
    bloom.add(b'value 2')

    assert int(
        bloom
    ) == 1090215279796298345343057319992441901006450066263950115824040002588950485497113027143927523755823134941133023716890165043342811041924870874305880232180990464248298835944719578227183672673286106858273952584661686762419935928160959430409028732374024192153399763277382459194254234587232383494962731940352290891816707697788111127980409605093135659121120897102645250001200507634146244124778321795865777525978540960830042468420173693965828992647991129039043403835835590424035347457188427354145120006479590726476620907513681178254852999008485376
    def __init__(self,
                 status_code: bytes,
                 gas_used: int,
                 logs: Iterable[Log],
                 bloom: int = None) -> None:

        if bloom is None:
            bloomables = itertools.chain.from_iterable(log.bloomables
                                                       for log in logs)
            bloom = int(BloomFilter.from_iterable(bloomables))

        super(Receipt, self).__init__(
            status_code=status_code,
            gas_used=gas_used,
            bloom=bloom,
            logs=logs,
        )

        for log_idx, log in enumerate(self.logs):
            if log.address not in self.bloom_filter:
                raise ValidationError(
                    "The address from the log entry at position {0} is not "
                    "present in the provided bloom filter.".format(log_idx))
            for topic_idx, topic in enumerate(log.topics):
                if int32.serialize(topic) not in self.bloom_filter:
                    raise ValidationError(
                        "The topic at position {0} from the log entry at "
                        "position {1} is not present in the provided bloom "
                        "filter.".format(topic_idx, log_idx))
Beispiel #4
0
    def __init__(self,
                 header: BlockHeader,
                 transactions: Iterable[BaseTransaction] = None,
                 xmessage_sent: Iterable[StretchXMessage] = None,
                 xmessage_received: Iterable[StretchXMessageReceived] = None,
                 uncles: Iterable[BlockHeader] = None) -> None:
        if transactions is None:
            transactions = []
        if xmessage_sent is None:
            xmessage_sent = []
        if xmessage_received is None:
            xmessage_received = []
        if uncles is None:
            uncles = []

        self.bloom_filter = BloomFilter(header.bloom)

        rlp.Serializable.__init__(
            self,
            header=header,
            transactions=transactions,
            xmessage_sent=xmessage_sent,
            xmessage_received=xmessage_received,
            uncles=uncles,
        )
Beispiel #5
0
 def add_receipt_to_header(self, old_header: BlockHeaderAPI,
                           receipt: ReceiptAPI) -> BlockHeaderAPI:
     return old_header.copy(
         bloom=int(BloomFilter(old_header.bloom) | receipt.bloom),
         gas_used=receipt.gas_used,
         state_root=self.state.make_state_root(),
     )
Beispiel #6
0
    def add_transaction(self, transaction, computation, block):
        """
        Add a transaction to the given block and
        return `trie_data` to store the transaction data in chaindb in VM layer.

        Update the bloom_filter, transaction trie and receipt trie roots, bloom_filter,
        bloom, and used_gas of the block.

        :param transaction: the executed transaction
        :param computation: the Computation object with executed result
        :param block: the Block which the transaction is added in
        :type transaction: Transaction
        :type computation: Computation
        :type block: Block

        :return: the block and the trie_data
        :rtype: (Block, dict[bytes, bytes])
        """
        receipt = self.make_receipt(transaction, computation)
        self.gas_used = receipt.gas_used

        new_header = block.header.copy(
            bloom=int(BloomFilter(block.header.bloom) | receipt.bloom),
            gas_used=receipt.gas_used,
            state_root=self.state_root,
        )
        new_block = block.copy(
            header=new_header,
            transactions=tuple(block.transactions) + (transaction, ),
        )

        return new_block, receipt
Beispiel #7
0
 def add_receipt_to_header(self, old_header: BlockHeaderAPI,
                           receipt: ReceiptAPI) -> BlockHeaderAPI:
     # Skip merkelizing the account data and persisting it to disk on every transaction.
     # Starting in Byzantium, this is no longer necessary, because the state root isn't
     # in the receipt anymore.
     return old_header.copy(
         bloom=int(BloomFilter(old_header.bloom) | receipt.bloom),
         gas_used=receipt.gas_used,
     )
    async def poll_zeroex_logs_loop(self):
        while True:
            try:
                new_blocks: List[
                    AttributeDict] = await self._new_blocks_queue.get()

                for block in new_blocks:
                    block_bloom_filter = BloomFilter(
                        int.from_bytes(block["logsBloom"], byteorder='big'))
                    if FILL_EVENT_TOPIC in block_bloom_filter:
                        # Potentially a Fill for an order hash we are interested in
                        order_hashes: List[str] = []
                        for order_hash in self._watch_order_hashes:
                            if bytes.fromhex(order_hash) in block_bloom_filter:
                                order_hashes.append("0x" + order_hash)
                        if len(order_hashes) > 0:
                            fill_entries = await self._get_logs({
                                'topics': [
                                    "0x6869791f0a34781b29882982cc39e882768cf2c96995c2a110c577c53bc932d5",
                                    None, None, order_hashes
                                ],
                                'blockhash':
                                block["hash"].hex()
                            })

                            for fill_entry in fill_entries:
                                event_data: AttributeDict = get_event_data(
                                    ABICodec(registry), self._event_abi,
                                    fill_entry)
                                event_data_tx_hash: HexBytes = event_data[
                                    "transactionHash"]
                                # Skip any duplicates
                                if event_data_tx_hash not in self._event_cache:
                                    await self._handle_event_data(event_data)

                            # Mark all of these as processed now, since each tx may contain multiple Fill logs
                            for fill_entry in fill_entries:
                                event_data_tx_hash: HexBytes = fill_entry[
                                    "transactionHash"]
                                if event_data_tx_hash not in self._event_cache:
                                    self._event_cache.add(event_data_tx_hash)

            except asyncio.CancelledError:
                raise
            except asyncio.TimeoutError:
                continue
            except Exception:
                self.logger().network(
                    "Unknown error trying to fetch new events for ZeroEx fills.",
                    exc_info=True,
                    app_warning_msg=
                    "Unknown error trying to fetch new events for ZeroEx fills. "
                    "Check wallet network connection")
Beispiel #9
0
    def __init__(self, header, transactions=None, uncles=None):
        if transactions is None:
            transactions = []
        if uncles is None:
            uncles = []

        self.bloom_filter = BloomFilter(header.bloom)

        super().__init__(
            header=header,
            transactions=transactions,
            uncles=uncles,
        )
Beispiel #10
0
def test_bloom_filter_extend_method(log_entries):
    bloom = BloomFilter()

    for address, topics in log_entries:
        bloom.extend([address])
        bloom.extend(topics)

    check_bloom(bloom, log_entries)
Beispiel #11
0
def test_casting_to_binary():
    bloom = BloomFilter()

    assert bin(bloom) == '0b0'

    bloom.add(b'value 1')
    bloom.add(b'value 2')

    assert bin(bloom) == (
        '0b1000000000000000000000000000000000000000000000000000000000000'
        '000000000000000000000000000000000000000000000000000100000000000'
        '000000000000000000000000000000000000000000000000000000000000000'
        '000000000000000000000000000000000000000000000000000000000000000'
        '000000000000000000000000000000000000000000000000000000000000000'
        '000000000000000000000000000000000000000000000000000000000000000'
        '010000000000000000000000000000000000000000000000000000000000000'
        '000000000000000000000000000000000000000000000000000000000000000'
        '000000000000000000000000000000000000000000000000000000000000000'
        '000000000000000000000000000000000000000000000000000000000000000'
        '000000000000000000000000000000000000000000000000000000000000000'
        '000000000000000000000000000000000000000000000000000000000000000'
        '000000000000000000000000000000000000000000000000000000000000000'
        '000000000000000000000000000000000000000000000000000000000000000'
        '000000000000000000010000000000000000000000000001000000000000000'
        '000000000000000000000000000000000000000000000000000000000000000'
        '000000000000000000000000000000000000000000000000000000000000000'
        '000000000000000000000000000000000000000000000000000000000000000'
        '000000000000000000000000000000000000000000000000000000000000000'
        '000000000000000000000000000000000000000000000000000000000000000'
        '000000000000000000000000000000000000000000000000000000000000000'
        '000000000000000000000000000000000000000000000000000000000000000'
        '000000000000000000000000000000000000000000000000000000000000000'
        '000000000000000000000000000000000000000000000000000000000000000'
        '000000000100000000000000000000000000000000000000000000000000000'
        '000000000000000000000000000000000000000000000000000000000000000'
        '000000000000000000000000000000000000000000000000000000000000000'
        '000000000000000000000000000000000000000000000000000000000000000'
        '00000000000000000000000')
Beispiel #12
0
def test_bloom_filter_add_method(log_entries):
    bloom = BloomFilter()

    for address, topics in log_entries:
        bloom.add(address)
        for topic in topics:
            bloom.add(topic)

    check_bloom(bloom, log_entries)
Beispiel #13
0
    def __init__(self, header, chaindb, transactions=None, uncles=None):
        self.chaindb = chaindb

        if transactions is None:
            transactions = []
        if uncles is None:
            uncles = []

        self.bloom_filter = BloomFilter(header.bloom)

        super(FrontierBlock, self).__init__(
            header=header,
            transactions=transactions,
            uncles=uncles,
        )
    def __init__(self,
                 state_root: bytes,
                 gas_used: int,
                 logs: Iterable[Log],
                 bloom: int=None) -> None:

        if bloom is None:
            bloomables = itertools.chain.from_iterable(log.bloomables for log in logs)
            bloom = int(BloomFilter.from_iterable(bloomables))

        super().__init__(
            state_root=state_root,
            gas_used=gas_used,
            bloom=bloom,
            logs=logs,
        )
Beispiel #15
0
    def __init__(self,
                 header: BlockHeader,
                 transactions: Iterable[BaseTransaction] = None,
                 uncles: Iterable[BlockHeader] = None) -> None:
        if transactions is None:
            transactions = []
        if uncles is None:
            uncles = []

        self.bloom_filter = BloomFilter(header.bloom)

        super().__init__(
            header=header,
            transactions=transactions,
            uncles=uncles,
        )
Beispiel #16
0
    def __init__(self,
                 header: BlockHeaderAPI,
                 transactions: Sequence[SignedTransactionAPI] = None,
                 uncles: Sequence[BlockHeaderAPI] = None) -> None:
        if transactions is None:
            transactions = []
        if uncles is None:
            uncles = []

        self.bloom_filter = BloomFilter(header.bloom)

        super().__init__(
            header=header,
            transactions=transactions,
            uncles=uncles,
        )
Beispiel #17
0
    def apply_transaction(self, transaction):
        """
        Apply the transaction to the current block. This is a wrapper around
        :func:`~evm.vm.state.State.apply_transaction` with some extra orchestration logic.
        """
        state_root, computation = self.state.apply_transaction(transaction)
        receipt = self.make_receipt(transaction, computation, self.state)
        # TODO: remove this mutation.
        self.state.gas_used = receipt.gas_used

        new_header = self.block.header.copy(
            bloom=int(BloomFilter(self.block.header.bloom) | receipt.bloom),
            gas_used=receipt.gas_used,
            state_root=state_root,
        )

        return new_header, receipt, computation
Beispiel #18
0
    def __init__(self, header, db, transactions=None, uncles=None):
        self.db = db

        if transactions is None:
            transactions = []
        if uncles is None:
            uncles = []

        self.bloom_filter = BloomFilter(header.bloom)
        self.transaction_db = Trie(db=self.db, root_hash=header.transaction_root)
        self.receipt_db = Trie(db=self.db, root_hash=header.receipt_root)

        super(FrontierBlock, self).__init__(
            header=header,
            transactions=transactions,
            uncles=uncles,
        )
Beispiel #19
0
    def apply_transaction(self, header, transaction):
        """
        Apply the transaction to the current block. This is a wrapper around
        :func:`~evm.vm.state.State.apply_transaction` with some extra orchestration logic.

        :param header: header of the block before application
        :param transaction: to apply
        """
        self.validate_transaction_against_header(header, transaction)
        state_root, computation = self.state.apply_transaction(transaction)
        receipt = self.make_receipt(header, transaction, computation, self.state)

        new_header = header.copy(
            bloom=int(BloomFilter(header.bloom) | receipt.bloom),
            gas_used=receipt.gas_used,
            state_root=state_root,
        )

        return new_header, receipt, computation
Beispiel #20
0
    def apply_transaction(self, transaction):
        """
        Apply the transaction to the vm in the current block.
        """
        state_root, computation = self.state.apply_transaction(transaction)
        receipt = self.make_receipt(transaction, computation, self.state)
        # TODO: remove this mutation.
        self.state.gas_used = receipt.gas_used

        new_header = self.block.header.copy(
            bloom=int(BloomFilter(self.block.header.bloom) | receipt.bloom),
            gas_used=receipt.gas_used,
            state_root=state_root,
        )
        self.block = self.block.copy(
            header=new_header,
            transactions=tuple(self.block.transactions) + (transaction,),
        )

        return self.block, receipt, computation
Beispiel #21
0
    def __init__(self,
                 header,
                 transactions=None,
                 receive_transactions=None,
                 reward_bundle=None):
        if transactions is None:
            transactions = []

        if receive_transactions is None:
            receive_transactions = []

        if reward_bundle is None:
            reward_bundle = StakeRewardBundle()

        self.bloom_filter = BloomFilter(header.bloom)

        super(HeliosTestnetBlock, self).__init__(
            header=header,
            transactions=transactions,
            receive_transactions=receive_transactions,
            reward_bundle=reward_bundle,
        )
Beispiel #22
0
    def apply_send_transaction(
            self,
            header: BlockHeader,
            transaction: BaseTransaction,
            caller_chain_address: Address,
            validate: bool = True
    ) -> Tuple[BlockHeader, Receipt, BaseComputation]:
        """
        Apply the transaction to the current block. This is a wrapper around
        :func:`~hvm.vm.state.State.apply_transaction` with some extra orchestration logic.

        :param header: header of the block before application
        :param transaction: to apply
        """
        #caller_chain_address = header.sender
        #this is a send transaction
        send_transaction = transaction
        receive_transaction = None
        if validate:
            self.validate_transaction_against_header(
                header, send_transaction=send_transaction)

        computation, _ = self.state.apply_transaction(
            send_transaction=send_transaction,
            caller_chain_address=caller_chain_address,
            receive_transaction=receive_transaction,
            validate=validate)
        if validate:
            receipt = self.make_receipt(header, computation, send_transaction)

            new_header = header.copy(
                bloom=int(BloomFilter(header.bloom) | receipt.bloom),
                gas_used=receipt.gas_used,
            )

            return new_header, receipt, computation
        else:
            return None, None, computation
Beispiel #23
0
    def get_deposit_transactions_from_block(self,
                                            height: int) -> List[Deposit]:

        try:
            ret_deposit_txs = []

            n_chain_lastest_height = self.myweb3.eth.blockNumber

            block_info = self.myweb3.eth.getBlock(BlockNumber(height),
                                                  full_transactions=True)

            included_contracts = []
            erc20_transfer_event = unhexlify(ERC20_TRANSFER_EVENT_HASH)

            n = int(hexlify(block_info.logsBloom).decode('latin1'), 16)
            bloom_filter = BloomFilter(n)

            # 测试合约地址是否存在
            if erc20_transfer_event in bloom_filter:  # 检查 transfer事件是否存在
                for contract_addr in ERC20_CONTRACTS_LIST:
                    con_addr = contract_addr.replace(
                        '0x', '').lower()  # 如果包含'0x'则去掉 '0x'
                    con_addr_bytes = unhexlify(con_addr)
                    if con_addr_bytes in bloom_filter:
                        included_contracts.append(con_addr)

            del bloom_filter

            for tx_data in block_info["transactions"]:

                # 如果是创建合约, to是 null  或者是 挖矿交易
                if tx_data['to'] is None:
                    self.logger.info('tx_data["to"] is None')
                    continue

                #因redis区分大小写, 所以统一使用小写进行redis匹配
                to_addr = str(tx_data['to']).lower()
                from_addr = str(tx_data['from']).lower()

                # if str(to_addr).lower() == '0xa1f5c76f14b3aeb1fd615f569c67993e8d890112':
                #     self.logger.info('-------------')

                if self.is_in_address_cache(address=to_addr):  # 普通的ETH充币

                    # 普通的ETH转账
                    deposit_address = self.session.query(Address)\
                                        .filter(Address.address == to_addr)\
                                        .first()

                    if deposit_address is None:
                        self.logger.warning(
                            f'not found address {to_addr} in databases!')
                        continue

                    deposit_tx = Deposit()

                    deposit_tx.tx_hash = to_hex(tx_data["hash"])
                    deposit_tx.token_name = 'ETH'
                    deposit_tx.notify_status = 0
                    deposit_tx.memo = None
                    deposit_tx.pro_id = deposit_address.pro_id
                    deposit_tx.from_addr = from_addr  # tx_data['from']
                    deposit_tx.to_addr = to_addr  #tx_data['to']
                    deposit_tx.amount = RoundDown(
                        Web3.fromWei(tx_data["value"], 'ether'))
                    deposit_tx.block_time = datetime.fromtimestamp(
                        int(block_info.timestamp)),
                    deposit_tx.tx_confirmations = n_chain_lastest_height - block_info[
                        'number']
                    deposit_tx.block_height = block_info["number"]

                    self.logger.info(f"found  ETH deposit  tx:{deposit_tx}")
                    ret_deposit_txs.append(deposit_tx)

                    self.refresh_deposit_address_balance(address=to_addr)
                    continue

                # ETH归集
                if self.is_in_address_cache(address=from_addr):
                    self.refresh_deposit_address_balance(address=from_addr)
                    pass

                # 继续判断是否包含 ERC20代币交易
                if 0 == len(included_contracts):
                    continue

                # 获取关心的ERC20代币转账
                erc20_deposit_tx = self._get_erc20_token_deposit(
                    tx_data, block_info, n_chain_lastest_height)

                if erc20_deposit_tx is not None:
                    ret_deposit_txs.append(erc20_deposit_tx)
                    self.logger.info(
                        f"found  ETH deposit  tx:{erc20_deposit_tx}")

                pass

            return ret_deposit_txs
        except Exception as e:
            # traceback.print_exc()
            self.logger.error(
                f"get_deposit_transactions_from_block({height}) error:{e}")
            time.sleep(2)
            raise e

        pass
Beispiel #24
0
from eth_bloom import BloomFilter

b = BloomFilter()
print(b'a value' in b)

print(type(b))
b.add(b'a value')
a = int(b)
print(bin(b))

print(b'a value' in b)
print(int(b))
print(len(bin(b)))

c = BloomFilter(bin(b))
print(b'a value' in b)

url = 'http://163.com'
print(bytes(url.encode('utf-8')) in b)

b.add(bytes(url.encode('utf-8')))
print(bytes(url.encode('utf-8')) in b)
Beispiel #25
0
class Sinanews(object):
    def __init__(self,mongodbutil):
        self.itemArray = []
        self.mongodbutil = mongodbutil
        originalBloom = self.readBloomValueFromFile()
        if originalBloom == '' :
            self.bloomFilter = BloomFilter()
        else:
            #self.bloomFilter = BloomFilter(int.from_bytes(originalBloom, byteorder='big'))
            self.bloomFilter = BloomFilter(int(originalBloom))
        self.urlExist = False

    def get_page(self,code,url):
        self.itemArray = []
        res = requests.get(url,timeout=10)
        res.encoding = "gbk"
        res.raise_for_status()
        if res.status_code == 200 :
            contentSoup = bs4.BeautifulSoup(res.text,'lxml')
            elems = contentSoup.select('#js_ggzx > li,.li_point > ul > li,.col02_22 > ul > li')
            for elem in elems:
                json = {}
                json['code'] = code
                ele = elem.select('span')
                json['date'] = ele[0].getText()[1:-1]
                s = json['date']
                ele = elem.select('a')
                json['title'] = ele[len(ele)-1].getText()
                print("date:{},title:{}".format(s,json['title']))
                json['href'] = ele[len(ele)-1].attrs['href']
                ret,content = self.get_content(json['href'])
                if ret != -1 :
                    time.sleep(4 * random.random())

                if ret == 0 :
                    json['content'] = content
                    self.itemArray.append(json)


    def get_content(self,url):
        content = ''
        ret = -1

        self.urlExist = bytes(url.encode('utf-8')) in self.bloomFilter
        if self.urlExist:
            print('This url:{} has existed'.format(url))
            return ret, content
        else:
            self.bloomFilter.add(bytes(url.encode('utf-8')))

        header = {
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'}
        res = requests.get(url,headers=header,timeout=10)
        res.encoding = "utf-8"
        try:
            res.raise_for_status()
        except Exception as err:
            print(err)

        if res.status_code == 200:
            soup = bs4.BeautifulSoup(res.text,'lxml')
            elems = soup.select('#artibody,.entry-content')
            if len(elems) > 0 :
                content = elems[0].getText()
                ret = 0
        return ret, content

    def get_item_array(self):
        return self.itemArray

    def writeBloomValueToFile(self):
        file = open(''.join((self.path(),'/bloom.txt')),'w+')
        file.write(str(self.bloomFilter.__int__()))
        file.close()

    def readBloomValueFromFile(self):
        file = None
        content = ''
        try:
            file = open(''.join((self.path(),'/bloom.txt')),'r')
            content = file.read()
            print(content)
            file.close()
        except Exception as err:
            print(err)

        return content

    # def addUrl(self,url):
    #     self.urlExist = bytes(url.encode('utf-8')) in self.bloomFilter
    #     if self.urlExist:
    #         print('This url:{} has existed'.format(url))
    #     else:
    #         self.bloomFilter.add(bytes(url.encode('utf-8')))


    def path(self):
        return os.path.dirname(__file__)
Beispiel #26
0
 def bloom_filter(self) -> BloomFilter:
     return BloomFilter(self.bloom)
Beispiel #27
0
import json
from eth_bloom import BloomFilter

data = json.load(open('data/addr_stats.json'))
b = BloomFilter()
for addr in data.keys():
    b.add(bytes(addr.encode()))
print(int(b))
print(bin(b))
Beispiel #28
0
def test_bloom_filter_from_iterable_method(log_entries):
    bloomables = itertools.chain.from_iterable(
        itertools.chain([address], topics) for address, topics in log_entries)
    bloom = BloomFilter.from_iterable(bloomables)
    check_bloom(bloom, log_entries)
Beispiel #29
0
    def apply_receive_transaction(
        self,
        header: BlockHeader,
        receive_transaction: BaseReceiveTransaction,
        caller_chain_address: Address,
        validate: bool = True
    ) -> Tuple[Optional[BlockHeader], Optional[Receipt], BaseComputation,
               Optional[BaseReceiveTransaction]]:
        """
        Apply the transaction to the current block. This is a wrapper around
        :func:`~hvm.vm.state.State.apply_transaction` with some extra orchestration logic.

        :param header: header of the block before application
        :param transaction: to apply
        """
        # Lets make sure we have this receivable transaction in the account
        receivable_tx_key = self.state.account_db.get_receivable_transaction(
            caller_chain_address, receive_transaction.send_transaction_hash)

        # Very first thing, check to see if this transaction has been received before:
        try:
            block_hash, index, is_receive = self.chaindb.get_transaction_index(
                receive_transaction.hash)
            if self.chaindb.is_in_canonical_chain(block_hash):
                raise ValidationError(
                    'Tried to import a receive transaction that has already been received in the canonical chain'
                )
        except TransactionNotFound:
            pass

        if receivable_tx_key is None:
            # There is no receivable transaction that matches this one.
            # now check to see if the block is in the canonical chain, but didnt have the transaction in it
            try:
                block_hash, index, is_receive = self.chaindb.get_transaction_index(
                    receive_transaction.send_transaction_hash)
                if block_hash == receive_transaction.sender_block_hash:
                    raise ValidationError(
                        'Receive transaction is invalid. We do have the send transaction and send block, but it has already been received.'
                    )
                else:
                    raise ValidationError(
                        'Receive transaction is invalid. We have already imported this transaction, but it was from another block.'
                    )
            except TransactionNotFound:
                if self.chaindb.is_in_canonical_chain(
                        receive_transaction.sender_block_hash):
                    raise ValidationError(
                        'Receive transaction is invalid. We have the sender block, but it didn\'t contain the send transaction'
                    )

            if self.chaindb.exists(receive_transaction.send_transaction_hash):
                self.logger.debug(
                    "The missing receivable transaction exists in the db but not canonical chain."
                )

            if self.chaindb.is_in_canonical_chain(
                    receive_transaction.sender_block_hash):
                self.logger.debug(
                    "The sender block of the missing receivable transaction is in the canonical chain. This must means the tx is in there, but wasnt saved to canonical transactions..."
                )

            raise ReceivableTransactionNotFound(
                "caller_chain_address = {}, send_transaction_hash = {}, sender_block_hash = {}"
                .format(
                    encode_hex(caller_chain_address),
                    encode_hex(receive_transaction.send_transaction_hash),
                    encode_hex(receive_transaction.sender_block_hash),
                ))

        else:
            #now lets get all of the relevant transactions in this chain
            try:

                if receive_transaction.is_refund:
                    #this is a refund transaction. We need to load the receive_transaction containing the refund and the send_transaction
                    refund_transaction = receive_transaction

                    block_hash, index, is_receive = self.chaindb.get_transaction_index(
                        refund_transaction.send_transaction_hash)

                    if block_hash != refund_transaction.sender_block_hash:
                        raise ValidationError(
                            "The sender_block_hash of this refund transaction doesn't match the block of the receive transaction"
                        )

                    if not is_receive:
                        raise ValidationError(
                            "This refund transaction references a send transaction. This is not allowed."
                        )

                    receive_transaction = self.chaindb.get_receive_transaction_by_index_and_block_hash(
                        block_hash,
                        index,
                        self.get_receive_transaction_class(),
                    )
                else:
                    refund_transaction = None

                block_hash, index, is_receive = self.chaindb.get_transaction_index(
                    receive_transaction.send_transaction_hash)

                if block_hash != receive_transaction.sender_block_hash:
                    raise ValidationError(
                        "The sender_block_hash of this receive transaction doesn't match the block of the send transaction"
                    )

                if is_receive:
                    raise ValidationError(
                        "This receive transaction references another receive transaction. This is not allowed."
                    )

                send_transaction = self.chaindb.get_transaction_by_index_and_block_hash(
                    block_hash,
                    index,
                    self.get_transaction_class(),
                )

            except TransactionNotFound:
                raise ReceivableTransactionNotFound()

            # we assume past this point that, if it is a receive transaction, the send transaction exists in account
            computation, processed_transaction = self.state.apply_transaction(
                send_transaction=send_transaction,
                caller_chain_address=caller_chain_address,
                receive_transaction=receive_transaction,
                refund_transaction=refund_transaction,
                validate=validate)

            if validate:
                receipt = self.make_receipt(header, computation,
                                            send_transaction,
                                            receive_transaction,
                                            refund_transaction)

                new_header = header.copy(
                    bloom=int(BloomFilter(header.bloom) | receipt.bloom),
                    gas_used=receipt.gas_used,
                )

                return new_header, receipt, computation, processed_transaction
            else:
                return None, None, computation, processed_transaction
Beispiel #30
0
def test_combining_filters():
    b1 = BloomFilter()
    b2 = BloomFilter()

    b1.add(b'a')
    b1.add(b'b')
    b1.add(b'c')

    b2.add(b'd')
    b2.add(b'e')
    b2.add(b'f')

    b1.add(b'common')
    b2.add(b'common')

    assert b'a' in b1
    assert b'b' in b1
    assert b'c' in b1

    assert b'a' not in b2
    assert b'b' not in b2
    assert b'c' not in b2

    assert b'd' in b2
    assert b'e' in b2
    assert b'f' in b2

    assert b'd' not in b1
    assert b'e' not in b1
    assert b'f' not in b1

    assert b'common' in b1
    assert b'common' in b2

    b3 = b1 | b2

    assert b'a' in b3
    assert b'b' in b3
    assert b'c' in b3
    assert b'd' in b3
    assert b'e' in b3
    assert b'f' in b3
    assert b'common' in b3

    b4 = b1 + b2

    assert b'a' in b4
    assert b'b' in b4
    assert b'c' in b4
    assert b'd' in b4
    assert b'e' in b4
    assert b'f' in b4
    assert b'common' in b4

    b5 = BloomFilter(int(b1))
    b5 |= b2

    assert b'a' in b5
    assert b'b' in b5
    assert b'c' in b5
    assert b'd' in b5
    assert b'e' in b5
    assert b'f' in b5
    assert b'common' in b5

    b6 = BloomFilter(int(b1))
    b6 += b2

    assert b'a' in b6
    assert b'b' in b6
    assert b'c' in b6
    assert b'd' in b6
    assert b'e' in b6
    assert b'f' in b6
    assert b'common' in b6