def test_count():
    storage = MsgList()
    assert storage.count() == 0
    storage.append(Message(message="test"))
    storage.append(Message(message="test"))
    storage.append(Message(message="test"))
    assert storage.count() == 3
Esempio n. 2
0
 def _address_from_vout(self, txid, vout):
     script = vout.scriptPubKey
     if len(script) >= 38 and script[:6] == bitcoin.core.WITNESS_COINBASE_SCRIPTPUBKEY_MAGIC:
         return
     try:
         script = CScript(vout.scriptPubKey)
         if script.is_unspendable():
             self.log.warn("Unspendable %s" % vout.scriptPubKey)
             if vout.scriptPubKey[2:4] == b'\xfe\xab':
                 m = vout.scriptPubKey[4:].decode('utf-8')
                 Message.create(message=m)
             return
         return str(TX_CBitcoinAddress.from_scriptPubKey(script))
     except:
         self.log.warn('scriptPubKey invalid txid=%s scriptPubKey=%s value=%s' % (txid, b2lx(vout.scriptPubKey), vout.nValue))
Esempio n. 3
0
    async def _send_msg(self, msg: Message) -> Dict:
        res: Dict = {'acknowledgment': BROADCAST_STATUS_FAILED}
        async with ClientSession() as client:
            try:
                async with client.post(urljoin(self.url, 'append-msg'),
                                       json=msg.dict()) as resp:
                    res.update(await resp.json())
            except ClientConnectorError as e:
                # logger.error(f'Failure connection on the node [{self.name}]')
                raise e

            res['name'] = self.name

        return res
Esempio n. 4
0
    def parse_vout(self, tx, txid, tx_data, vout, idx, batch=None, blockHeight=None):
        script = vout.scriptPubKey
        if len(script) >= 38 and script[:6] == bitcoin.core.WITNESS_COINBASE_SCRIPTPUBKEY_MAGIC:
            return
        try:
            script = CScript(vout.scriptPubKey)
            if script.is_unspendable():
                self.log.warn("Unspendable %s" % vout.scriptPubKey)
                if vout.scriptPubKey[2:4] == b'\xfe\xab':
                    m = vout.scriptPubKey[4:].decode('utf-8')
                    Message.create(message=m)
                return
            address = str(TX_CBitcoinAddress.from_scriptPubKey(script))
        except:
            self.log.warn('scriptPubKey invalid txid=%s scriptPubKey=%s value=%s' % (txid, b2lx(vout.scriptPubKey), vout.nValue))
            return
        value = vout.nValue
        self.pututxo(txid, idx, address, value, wb=batch, scriptPubKey=vout.scriptPubKey.hex(), blockHeight=blockHeight)
        tx_data["vout"].append({"address": address, "value": value, "vout": idx})
        if address in tx_data["addresses_out"]:
            tx_data["addresses_out"][address] += value
        else:
            tx_data["addresses_out"][address] = value
        tx_data["output_value"] += value

        # Update address tracking only when non-mempool (batch is not none)
        if batch:
            self.log.debug("Updating address %s with value %s" % (address, value))
            if address in self.address_changes:
                self.address_changes[address]['balance'] += value
                self.address_changes[address]['received'] += value
            else:
                self.address_changes[address] = {
                    'balance': value,
                    'received': value,
                    'sent': 0,
                }
Esempio n. 5
0
    async def append_message(self, request: web.Request) -> web.Response:
        if random.random() < self.error_prob:
            logger.opt(colors=True).info(
                "<bold><red>Emulate Internal server error</red></bold>")
            return web.json_response({"status": "internal server error"},
                                     status=500)

        # emulate delay
        if int(self.delay) > 0:
            delay = random.random() * 10
            logger.opt(colors=True).info(
                f"<bold><red>Emulate delay: {delay:.4}</red></bold>")
            await asyncio.sleep(delay)

        data = await request.json()
        logger.opt(colors=True).info(
            f'<yellow>Receive a message on node {data}</yellow>')

        self.msg_storage.append(Message(**data))

        logger.opt(colors=True).info(
            f'<yellow>Append a message on node {data}</yellow>')
        return web.json_response({'ack': 'OK'})
Esempio n. 6
0
    async def replicate_msg(self, data: AppendMessage):
        write_concern = data.w

        # override can`t be bigger than count nodes
        write_concern = write_concern if write_concern <= len(
            self.nodes) else len(self.nodes)
        logger.info(f'Running with write concert "{write_concern}"')

        if self.check_quorum():
            error_message = f'Not enough nodes in quorum, only {self.get_count_of_live_nodes()} nodes alive'
            raise QuorumException(message=error_message)

        msg = Message(message=data.message,
                      id=int(time.time() * 1000.0),
                      order=self.msg_list.count())
        self.msg_list.append(msg)
        logger.debug(f"Append message: {{{msg}}} on [MASTER]")

        self._push_message(msg)

        tasks = [node.process() for node in self.nodes]
        n_of_confirmed_task = 0

        done, pending = await wait_n(tasks, n=write_concern)

        for task in done:
            try:
                await task
            except Exception as e:
                logger.exception(e)
            else:
                n_of_confirmed_task += 1

        if n_of_confirmed_task < write_concern:
            raise WriteConcertError

        asyncio.create_task(self._handle_unfinished_tasks(pending))
def test_append_message():
    storage = MsgList()
    assert storage.get_all() == []
    storage.append(Message(message="test"))
    assert storage.count() == 1