Example #1
0
    def setUpClass(cls):
        nodelist = NodeList()
        nodelist.update_nodes(steem_instance=Steem(node=nodelist.get_nodes(
            normal=True, appbase=True),
                                                   num_retries=10))
        cls.bts = Steem(node=nodelist.get_nodes(),
                        nobroadcast=True,
                        keys={"active": wif},
                        num_retries=10)
        b = Blockchain(steem_instance=cls.bts)
        num = b.get_current_block_num()
        cls.start = num - 25
        cls.stop = num

        cls.testnet = Steem(node="https://testnet.steemitdev.com",
                            nobroadcast=True,
                            keys={"active": wif},
                            num_retries=10)
        # from getpass import getpass
        # self.bts.wallet.unlock(getpass())
        set_shared_steem_instance(cls.bts)
        cls.bts.set_default_account("test")
        b = Blockchain(steem_instance=cls.testnet)
        num = b.get_current_block_num()
        cls.start_testnet = num - 25
        cls.stop_testnet = num
Example #2
0
    def read_missing_block_data(self, start_block=None):
        # Go trough all transfer ops
        cnt = 0
        blockchain = Blockchain()
        current_block = blockchain.get_current_block_num()

        if start_block is not None:
            trx_num = start_block["trx_num"]
            block_num = start_block["block_num"]
            start_block = block_num

            # print("account %s - %d" % (account["name"], start_block))
        else:
            trx_num = 0
            block_num = 0
            start_block = current_block - self.block_history

        data = []
        for op in blockchain.stream(start=start_block,
                                    stop=current_block,
                                    only_ops=self.only_ops,
                                    only_virtual_ops=self.only_virtual_ops):
            if op["block_num"] < start_block:
                # last_block = op["block"]
                continue
            elif op["block_num"] == start_block:

                if op["trx_num"] <= trx_num:
                    continue
            data.append(op)

            cnt += 1
        return data
Example #3
0
def profiling(name_list):
    stm = Steem()
    set_shared_steem_instance(stm)
    del stm
    print("start")
    for name in name_list:
        print("account: %s" % (name))
        acc = Account(name)
        max_index = acc.virtual_op_count()
        print(max_index)
        stopTime = datetime(2018, 4, 22, 0, 0, 0)
        hist_elem = None
        for h in acc.history_reverse(stop=stopTime):
            hist_elem = h
        print(hist_elem)
    print("blockchain")
    blockchain_object = Blockchain()
    current_num = blockchain_object.get_current_block_num()
    startBlockNumber = current_num - 20
    endBlockNumber = current_num
    block_elem = None
    for o in blockchain_object.ops(start=startBlockNumber, stop=endBlockNumber):
        print("block %d" % (o["block_num"]))
        block_elem = o
    print(block_elem)
    def find_steem_tx(self, tx_data: dict, last_blocks=15) -> dict:
        """
        Used internally to get the transaction ID after a Steem transaction has been broadcasted.

        See :py:meth:`.send_token` and :py:meth:`.issue_token` for how this is used.

        :param dict tx_data:      Transaction data returned by a beem broadcast operation, must include ``signatures``
        :param int last_blocks:   Amount of previous blocks to search for the transaction
        :return dict:             Transaction data from the blockchain, see below.
        
        **Return format:**

        .. code-block:: js

            {
                transaction_id, ref_block_num, ref_block_prefix, expiration,
                operations, extensions, signatures, block_num, transaction_num
            }
        
        :return None:             If the transaction wasn't found, ``None`` will be returned.
        """
        from beem.blockchain import Blockchain
        # Code taken/based from @holgern/beem blockchain.py
        chain = Blockchain(steem_instance=self.steem, mode='head')
        current_num = chain.get_current_block_num()
        for block in chain.blocks(start=current_num - last_blocks, stop=current_num + 5):
            for tx in block.transactions:
                if sorted(tx["signatures"]) == sorted(tx_data["signatures"]):
                    return tx
        return None
Example #5
0
 def test_stream2(self):
     bts = self.bts
     b = Blockchain(steem_instance=bts)
     stop_block = b.get_current_block_num()
     start_block = stop_block - 10
     ops_stream = []
     for op in b.stream(start=start_block, stop=stop_block):
         ops_stream.append(op)
     self.assertTrue(len(ops_stream) > 0)
Example #6
0
 def stream_blocks(self, start=None):
     blockchain = Blockchain()
     current_block = blockchain.get_current_block_num()
     ops = []
     for op in blockchain.stream(start=start,
                                 stop=current_block,
                                 only_ops=self.only_ops,
                                 only_virtual_ops=self.only_virtual_ops):
         ops.append(op)
     return ops
Example #7
0
def listen_blockchain_ops(opNames: list):
    """Listens to Steem blockchain and yields specified operations.

    :param opNames: List of operations to yield
    :type opNames: list
    """
    bc = Blockchain(mode="head")
    block_num = bc.get_current_block_num()
    for op in bc.stream(opNames=opNames, start=block_num, threading=True):
        yield op
Example #8
0
class SteemStream:
    def __init__(self, operations=[]):
        self.blockchain = Blockchain(mode="head")
        self.operations = operations
        self.last_streamed_block = 0
        self.max_batch_size = 50
        self.threading = False

    def run(self, callback=default_callback, lookback=0, start=-1, days=-1):
        try:
            if lookback > 0 or start > 0 or days > 0:
                if self.last_streamed_block == 0:
                    if start > 0:
                        start_block = start
                    elif lookback > 0:
                        start_block = self.blockchain.get_current_block_num() - int(lookback) #200000
                    else:
                        start_date = days_ago(days)
                        start_block = self.blockchain.get_estimated_block_num(start_date)
                else:
                    start_block = self.last_streamed_block + 1
                stop_block = self.blockchain.get_current_block_num()

                logger.info("Streaming for operations {} has started from block {} to {}".format(self.operations, start_block, stop_block))
                for ops in self.blockchain.stream(opNames=self.operations,
                            start=start_block, stop=stop_block,
                            max_batch_size=self.max_batch_size, threading=self.threading, thread_num=8):
                    try:
                        callback(ops)
                    except:
                        logger.error("Failed when procssing operation {} with error: {}".format(ops, traceback.format_exc()))
            else:
                logger.info("Streaming for operations {} has started from the latest blocks".format(self.operations))
                for ops in self.blockchain.stream(opNames=self.operations,
                            max_batch_size=self.max_batch_size, threading=self.threading, thread_num=8):
                    try:
                        callback(ops)
                    except:
                        logger.error("Failed when procssing operation {} with error: {}".format(ops, traceback.format_exc()))
        except:
            logger.error("Failed when streaming operations {} with error: {}".format(self.operations, traceback.format_exc()))
Example #9
0
 def test_stream2(self, node_param):
     if node_param == "normal":
         bts = self.bts
     else:
         bts = self.testnet
     b = Blockchain(steem_instance=bts)
     stop_block = b.get_current_block_num()
     start_block = stop_block - 10
     ops_stream = []
     for op in b.stream(start=start_block, stop=stop_block):
         ops_stream.append(op)
     self.assertTrue(len(ops_stream) > 0)
Example #10
0
    def setUpClass(cls):
        cls.bts = Steem(node=get_hive_nodes(),
                        nobroadcast=True,
                        keys={"active": wif},
                        num_retries=10)
        b = Blockchain(blockchain_instance=cls.bts)
        num = b.get_current_block_num()
        cls.start = num - 5
        cls.stop = num

        # from getpass import getpass
        # self.bts.wallet.unlock(getpass())
        set_shared_blockchain_instance(cls.bts)
Example #11
0
 def test_wait_for_and_get_block(self, node_param):
     if node_param == "non_appbase":
         bts = self.bts
     else:
         bts = self.appbase
     b = Blockchain(steem_instance=bts, max_block_wait_repetition=6)
     start_num = b.get_current_block_num()
     blocknum = start_num
     last_fetched_block_num = None
     for i in range(3):
         block = b.wait_for_and_get_block(blocknum)
         last_fetched_block_num = block.block_num
         blocknum = last_fetched_block_num + 2
     self.assertEqual(last_fetched_block_num, start_num + 4)
Example #12
0
 def test_blockchain(self):
     bts = self.bts
     b = Blockchain(steem_instance=bts)
     num = b.get_current_block_num()
     self.assertTrue(num > 0)
     self.assertTrue(isinstance(num, int))
     block = b.get_current_block()
     self.assertTrue(isinstance(block, Block))
     self.assertTrue((num - block.identifier) < 3)
     block_time = b.block_time(block.identifier)
     self.assertEqual(block.time(), block_time)
     block_timestamp = b.block_timestamp(block.identifier)
     timestamp = int(time.mktime(block.time().timetuple()))
     self.assertEqual(block_timestamp, timestamp)
def hour_active(chain):
        nodelist = NodeList()
        nodelist.update_nodes()
        if chain=='steem':
                s = Steem(node=nodelist.get_steem_nodes())
        else:
                s = Steem(node=nodelist.get_hive_nodes())
        b=Blockchain(s)
        bl_=[]
        bl_num=int(b.get_current_block_num())
        bl_num_=bl_num-1250
        bl=b.blocks(bl_num_,bl_num)
        for i in bl:
                bl_.append(i['transactions'])

	
        x=('follower','account','voter','from','author')
        account=[]
        new=[]
        for i in x:
                acc=re.findall('"'+i+'":"(.+?)"',str(bl_))
                for l in acc:
                        if l not in account:
                                account.append(l)
        if chain=='steem':
                file=open('active_acc_steem.txt','r')
                old=file.readlines()
                file.close()
                file=open('active_acc_steem.txt','a')
                for i in account:
                        if i+'\n' not in old:
                                file.write(str(i)+'\n')
                                new.append(i)
                file.close()
        else:
                file=open('active_acc_hive.txt','r')
                old=file.readlines()
                file.close()
                file=open('active_acc_hive.txt','a')
                for i in account:
                        if i+'\n' not in old:
                                file.write(str(i)+'\n')
                                new.append(i)
                file.close()
                
        print ('one hour accounts '+chain,len(account))
        print ('one hour brand new '+chain,len(new))
        print ('total ACTIVE accounts '+chain,len(old))
Example #14
0
    def setUpClass(cls):
        nodelist = NodeList()
        nodelist.update_nodes(steem_instance=Steem(
            node=nodelist.get_nodes(exclude_limited=False), num_retries=10))
        cls.bts = Steem(node=nodelist.get_nodes(exclude_limited=True),
                        nobroadcast=True,
                        keys={"active": wif},
                        num_retries=10)
        b = Blockchain(steem_instance=cls.bts)
        num = b.get_current_block_num()
        cls.start = num - 25
        cls.stop = num

        # from getpass import getpass
        # self.bts.wallet.unlock(getpass())
        set_shared_steem_instance(cls.bts)
Example #15
0
    def setUpClass(cls):
        cls.bts = Steem(
            node=nodes,
            nobroadcast=True,
            num_retries=10,
            keys={"active": wif},
        )
        # from getpass import getpass
        # self.bts.wallet.unlock(getpass())
        set_shared_steem_instance(cls.bts)
        cls.bts.set_default_account("test")

        b = Blockchain(steem_instance=cls.bts)
        num = b.get_current_block_num()
        cls.start = num - 25
        cls.stop = num
Example #16
0
    def setUpClass(cls):
        cls.bts = Steem(
            node=get_node_list(appbase=True, testing=False),
            nobroadcast=True,
            num_retries=10,
            keys={"active": wif},
        )
        # from getpass import getpass
        # self.bts.wallet.unlock(getpass())
        set_shared_steem_instance(cls.bts)
        cls.bts.set_default_account("test")

        b = Blockchain(steem_instance=cls.bts)
        num = b.get_current_block_num()
        cls.start = num - 25
        cls.stop = num
        cls.max_batch_size = 1  # appbase does not support batch rpc calls at the momement (internal error)
Example #17
0
    def setUpClass(cls):
        cls.bts = Steem(
            node=get_hive_nodes(),
            nobroadcast=True,
            timeout=30,
            num_retries=30,
        )
        # from getpass import getpass
        # self.bts.wallet.unlock(getpass())
        set_shared_steem_instance(cls.bts)
        cls.bts.set_default_account("test")

        b = Blockchain(steem_instance=cls.bts)
        num = b.get_current_block_num()
        # num = 23346630
        cls.start = num - 25
        cls.stop = num
Example #18
0
async def main():
    blocks = []
    hive = Hive(HIVE_NODES)
    chain = Blockchain(blockchain_instance=hive)
    print(f"\n [{datetime.utcnow()!s}] Loading last {NUM_BLOCKS} blocks using beem ... \n\n")
    start_time = time.time_ns()
    current_num = chain.get_current_block_num()
    for block in chain.blocks(start=current_num - NUM_BLOCKS, stop=current_num):
        blocks.append(block)
    end_time = time.time_ns()

    print(f"\n [{datetime.utcnow()!s}] Total blocks:", len(blocks), "\n")
    start_time, end_time = Decimal(start_time), Decimal(end_time)
    start_secs = start_time / SECS_NS
    end_secs = end_time / SECS_NS
    print("Start Time:", dec_round(start_secs, 4), "seconds")
    print("End Time:", dec_round(end_secs, 4), "seconds\n")
    print("Total Time:", dec_round(end_secs - start_secs, 4), "seconds\n")
Example #19
0
    def test_wait_for_and_get_block(self):
        bts = self.bts
        b = Blockchain(steem_instance=bts, max_block_wait_repetition=18)
        start_num = b.get_current_block_num()
        blocknum = start_num
        last_fetched_block_num = None
        for i in range(3):
            block = b.wait_for_and_get_block(blocknum)
            last_fetched_block_num = block.block_num
            blocknum = last_fetched_block_num + 1
        self.assertEqual(last_fetched_block_num, start_num + 2)

        b2 = Blockchain(steem_instance=bts, max_block_wait_repetition=1)
        with self.assertRaises(BlockWaitTimeExceeded):
            for i in range(300):
                block = b2.wait_for_and_get_block(blocknum)
                last_fetched_block_num = block.block_num
                blocknum = last_fetched_block_num + 2
Example #20
0
    def find_steem_tx(self, tx_data, last_blocks=15) -> Optional[dict]:
        """
        Used internally to get the transaction ID after a transaction has been broadcasted

        :param dict tx_data:      Transaction data returned by a beem broadcast operation, must include 'signatures'
        :param int last_blocks:   Amount of previous blocks to search for the transaction
        :return dict:             Transaction data from the blockchain {transaction_id, ref_block_num, ref_block_prefix,
                                  expiration, operations, extensions, signatures, block_num, transaction_num}

        :return None:             If the transaction wasn't found, None will be returned.
        """
        # Code taken/based from @holgern/beem blockchain.py
        chain = Blockchain(steem_instance=self.rpc, mode='head')
        current_num = chain.get_current_block_num()
        for block in chain.blocks(start=current_num - last_blocks, stop=current_num + 5):
            for tx in block.transactions:
                if sorted(tx["signatures"]) == sorted(tx_data["signatures"]):
                    return tx
        return None
Example #21
0
def main(conn, logger, debug=False):
    # Main Loop
    s = Steem(node=nodes)
    theChain = Blockchain(steem_instance=s, mode="head")

    Start_block_num = read_blocknum_fromfile("virtual_ops_block.txt")
    if not Start_block_num:
        Start_block_num = theChain.get_current_block_num()


#  print('Start For loop')
    try:
        for block in theChain.stream(only_virtual_ops=True,
                                     start=Start_block_num):
            print("Try add to DB")
            addblock_to_db(block, conn, logger)

    except Exception as e:
        return
Example #22
0
    def setUpClass(cls):
        nodelist = NodeList()
        nodelist.update_nodes(steem_instance=Steem(node=nodelist.get_nodes(normal=True, appbase=True), num_retries=10))
        cls.bts = Steem(
            node=nodelist.get_nodes(),
            nobroadcast=True,
            timeout=30,
            num_retries=30,
        )
        # from getpass import getpass
        # self.bts.wallet.unlock(getpass())
        set_shared_steem_instance(cls.bts)
        cls.bts.set_default_account("test")

        b = Blockchain(steem_instance=cls.bts)
        num = b.get_current_block_num()
        # num = 23346630
        cls.start = num - 25
        cls.stop = num
Example #23
0
    def setUpClass(cls):
        nodelist = NodeList()
        nodelist.update_nodes(steem_instance=Steem(node=nodelist.get_nodes(normal=True, appbase=True), num_retries=10))
        cls.bts = Steem(
            node=nodelist.get_nodes(normal=False, appbase=True, dev=True),
            nobroadcast=True,
            num_retries=10,
            timeout=30,
            use_condenser=False,
            keys={"active": wif},
        )
        # from getpass import getpass
        # self.bts.wallet.unlock(getpass())
        set_shared_steem_instance(cls.bts)
        cls.bts.set_default_account("test")

        b = Blockchain(steem_instance=cls.bts)
        num = b.get_current_block_num()
        cls.start = num - 100
        cls.stop = num
        cls.max_batch_size = 1  # appbase does not support batch rpc calls at the momement (internal error)
Example #24
0
def main(conn, logger, debug=False):
    s = Steem(node=nodes)

    theChain = Blockchain(steem_instance=s, mode="head")
    #  print('Start For loop')

    Start_block_num = read_blocknum_fromfile("ops_block.txt")
    if not Start_block_num:
        Start_block_num = theChain.get_current_block_num()

    try:
        for block in theChain.stream(start=Start_block_num):
            #      print("Run Again")
            #      print(f"{block['block_num']}")
            yay = addblock_to_db(block, conn, logger)


#      print("Got out ok")

    except Exception as e:
        logger.error(f"Error in Stream: {e}")
        return
Example #25
0
    def init_account_hist(self):
        if self.hist_account is None:
            return
        b = Blockchain(steem_instance=self.stm)
        latest_block_num = b.get_current_block_num()
        start_block_num = latest_block_num - (20 * 60 * 24)
        self.account_history = []
        self.account_hist_info = {"start_block": 0, "trx_ids": []}
        self.append_hist_info = {"start_block": 0, "trx_ids": []}

        if self.db.has_account_hist():
            self.account_history, trx_ids = self.db.load_account_hist()
            if self.account_history[0]["block"] <= start_block_num:
                self.append_hist_info["start_block"] = self.account_history[
                    -1]["block"]
                self.append_hist_info["trx_ids"] = trx_ids
                return

        self.lastUpvotesListWidget.clear()
        self.lastCurationListWidget.clear()
        self.lastAuthorListWidget.clear()
        self.accountHistListWidget.clear()
        start_block = 0
        trx_ids = []
        for op in self.hist_account.history(start=start_block_num):
            if op["block"] < start_block:
                continue
            elif op["block"] == start_block:
                if op["trx_id"] in trx_ids:
                    continue
                else:
                    trx_ids.append(op["trx_id"])
            else:
                trx_ids = [op["trx_id"]]
            start_block = op["block"]
            self.account_history.append(op)
        self.append_hist_info["start_block"] = start_block
        self.append_hist_info["trx_ids"] = trx_ids
class LatestPostManager():
    def __init__(self):
        self.mysql_con = config.get_connection()
        if self.mysql_con is None:
            print(
                "[INFO] Can't start Latest Post Manager because of an mysql database error!"
            )
            return
        self.mysql_cursor = self.mysql_con.cursor()
        self.query = "INSERT INTO latest_posts (author, permlink, category, timestamp) VALUES (%s, %s, %s, %s);"

        self.chain = Blockchain(
            blockchain_instance=Hive())  #node=conf.HIVE_NODES[5]

        self.run_thread = Thread(target=self.run)
        self.run_thread.name = 'Get & Categorize Posts'
        self.run_thread.daemon = True
        self.run_thread.start()

    def enter_posts_by_block(self, block):
        for op in block.operations:
            if op['type'] == 'comment_operation':
                action = op['value']
                if action['parent_author'] == '':
                    # found post --> Categorize
                    _input = network.WordEmbedding.vectorize_text(
                        config.statics.Word2Vec,
                        html=action['body'],
                        text=action['title'] + ". ")
                    if _input is None:
                        # to short or error
                        continue

                    # Categorize
                    _output = config.statics.TextCNN(_input).cpu()

                    # Enter in Mysql
                    str_arr = ' '.join(map(str, _output.data[0].tolist()))
                    result = database.commit_query(
                        self.query,
                        (action['author'], action['permlink'], str_arr,
                         block["timestamp"].strftime("%d.%m.%YT%H:%M:%S")))
                    if result == -1:
                        print("[WARNING] Can't enter post in database!")
                        time.sleep(5)

    def clean_up(self):
        # TODO: Implement sorting order by timestamp
        query = "SELECT timestamp FROM latest_posts;"
        for item in database.read_query(query, None):
            timestamp = datetime.strptime(item[0], "%d.%m.%YT%H:%M:%S")

            if timestamp < (datetime.utcnow() - timedelta(days=5)):
                result = database.commit_query(
                    "DELETE FROM latest_posts WHERE timestamp=%s;",
                    (item[0], ))

    def run(self):
        current_num = self.chain.get_current_block_num() - int(
            60 * 60 * 24 * 3 / 3
        )  # Get all posts from the last 3 days because it takes a long time to get all and when it finished, the clean_up begins
        while True:
            if current_num < self.chain.get_current_block_num():
                # if block is available
                try:
                    for block in self.chain.blocks(start=current_num,
                                                   stop=current_num):
                        self.enter_posts_by_block(block)
                except:
                    pass

                current_num += 1
                if current_num % 100 == 0:
                    self.clean_up()
                else:
                    time.sleep(0.5)

            else:
                # wait until new block is created
                # Using time for cleanup
                self.clean_up()
def benchmark_node_blocks(node,
                          num_retries=10,
                          num_retries_call=10,
                          timeout=60,
                          how_many_seconds=30):
    block_count = 0
    sucessfull = False
    error_msg = None
    start_total = timer()
    start_time = timer()
    max_batch_size = None
    threading = False
    thread_num = 16

    last_block_id = 19273700
    try:
        stm = Steem(node=node,
                    num_retries=num_retries,
                    num_retries_call=num_retries_call,
                    timeout=timeout)
        blockchain = Blockchain(steem_instance=stm)

        last_block_id = int(blockchain.get_current_block_num() * 0.75)

        last_block = Block(last_block_id, steem_instance=stm)

        total_transaction = 0

        start_time = timer()
        for entry in blockchain.blocks(start=last_block_id,
                                       max_batch_size=max_batch_size,
                                       threading=threading,
                                       thread_num=thread_num):
            block_no = entry.identifier
            block_count += 1
            if not sucessfull:
                sucessfull = True
            if "block" in entry:
                trxs = entry["block"]["transactions"]
            else:
                trxs = entry["transactions"]

            for tx in trxs:
                for op in tx["operations"]:
                    total_transaction += 1
            if "block" in entry:
                block_time = (entry["block"]["timestamp"])
            else:
                block_time = (entry["timestamp"])

            if timer() - start_time > how_many_seconds or quit_thread:
                break
    except NumRetriesReached:
        error_msg = 'NumRetriesReached'
        sucessfull = False
    except KeyboardInterrupt:
        error_msg = 'KeyboardInterrupt'
        # quit = True
    except Exception as e:
        error_msg = str(e)
        sucessfull = False
    total_duration = float("{0:.2f}".format(timer() - start_time))
    return {
        'sucessfull': sucessfull,
        'node': node,
        'error': error_msg,
        'total_duration': total_duration,
        'count': block_count,
        'access_time': None
    }
def benchmark_block_diff(node,
                         num_retries=10,
                         num_retries_call=10,
                         timeout=60):
    block_count = 0
    history_count = 0
    access_time = timeout
    follow_time = 0
    sucessfull = False
    error_msg = None
    start_total = timer()
    block_diff = 0
    block_head_diff = 0
    try:
        stm = Steem(node=node,
                    num_retries=num_retries,
                    num_retries_call=num_retries_call,
                    timeout=timeout)

        b = Blockchain(steem_instance=stm)
        b_head = Blockchain(mode="head", steem_instance=stm)
        dhi_max = 0
        head_max = timedelta(0)
        for i in range(0, 5):
            utcnow = addTzInfo(datetime.utcnow())
            df_head = addTzInfo(
                datetime.utcnow()) - b_head.get_current_block()["timestamp"]
            diff_value = b_head.get_current_block_num(
            ) - b.get_current_block_num()
            if diff_value > dhi_max:
                dhi_max = diff_value
            if df_head > head_max:
                head_max = df_head

            time.sleep(3)

        block_head_diff = head_max.total_seconds()
        block_diff = dhi_max
        sucessfull = True
    except NumRetriesReached:
        error_msg = 'NumRetriesReached'
        sucessfull = False
    except KeyboardInterrupt:
        error_msg = 'KeyboardInterrupt'
        # quit = True
    except Exception as e:
        error_msg = str(e)
        sucessfull = False
    total_duration = float("{0:.2f}".format(timer() - start_total))
    block_diff = float("{0:.2f}".format(block_diff))
    block_head_diff = float("{0:.2f}".format(block_head_diff))
    return {
        'sucessfull': sucessfull,
        'node': node,
        'error': error_msg,
        'total_duration': total_duration,
        'access_time': None,
        'count': None,
        'diff_head_irreversible': block_diff,
        'head_delay': block_head_diff
    }
Example #29
0
class Distribubot:
    def __init__(self, config, data_file, hived_instance):
        self.config = config
        self.data_file = data_file
        self.hive = hived_instance

        self.token_config = {}
        # add log stats
        self.log_data = {
            "start_time": 0,
            "last_block_num": None,
            "new_commands": 0,
            "stop_block_num": 0,
            "stop_block_num": 0,
            "time_for_blocks": 0
        }
        config_cnt = 0
        necessary_fields = [
            "token_account", "symbol", "min_token_in_wallet",
            "comment_command", "token_memo", "reply", "sucess_reply_body",
            "fail_reply_body", "no_token_left_body", "user_can_specify_amount",
            "usage_upvote_percentage", "no_token_left_for_today",
            "token_in_wallet_for_each_outgoing_token",
            "maximum_amount_per_comment", "count_only_staked_token"
        ]
        self.token_config = check_config(self.config["config"],
                                         necessary_fields, self.hive)

        self.blockchain = Blockchain(mode='head',
                                     blockchain_instance=self.hive)

    def run(self, start_block, stop_block):
        self.hive.wallet.unlock(self.config["wallet_password"])
        self.blockchain = Blockchain(mode='head',
                                     blockchain_instance=self.hive)
        current_block = self.blockchain.get_current_block_num()
        if stop_block is None or stop_block > current_block:
            stop_block = current_block

        if start_block is None:
            start_block = current_block
            last_block_num = current_block - 1
        else:
            last_block_num = start_block - 1

        self.log_data["start_block_num"] = start_block
        for op in self.blockchain.stream(start=start_block,
                                         stop=stop_block,
                                         opNames=["comment"]):
            self.log_data = print_block_log(self.log_data, op,
                                            self.config["print_log_at_block"])
            last_block_num = op["block_num"]

            if op["type"] == "comment":
                token = None

                for key in self.token_config:
                    if op["body"].find(
                            self.token_config[key]["comment_command"]) >= 0:
                        token = key
                if token is None:
                    continue
                if op["author"] == self.token_config[token]["token_account"]:
                    continue
                cnt = 0
                c_comment = None
                c_parent = None
                authorperm = construct_authorperm(op)
                use_tags_api = True
                while c_comment is None and cnt < 10:
                    cnt += 1
                    try:
                        c_comment = Comment(authorperm,
                                            use_tags_api=use_tags_api,
                                            blockchain_instance=self.hive)
                        c_comment.refresh()
                    except:
                        if cnt > 5:
                            use_tags_api = False
                        nodelist = NodeList()
                        nodelist.update_nodes()
                        self.hive = Hive(node=nodelist.get_hive_nodes(),
                                         num_retries=5,
                                         call_num_retries=3,
                                         timeout=15)
                        time.sleep(3)
                if cnt == 10 or c_comment is None:
                    logger.warn("Could not read %s/%s" %
                                (op["author"], op["permlink"]))
                    continue
                if 'depth' in c_comment:
                    if c_comment['depth'] == 0:
                        continue
                else:
                    if c_comment["parent_author"] == '':
                        continue

                if abs((c_comment["created"] -
                        op['timestamp']).total_seconds()) > 9.0:
                    logger.warn("Skip %s, as edited" % c_comment["authorperm"])
                    continue

                already_voted = False
                if self.token_config[token]["upvote_token_receiver"]:
                    parent_identifier = construct_authorperm(
                        c_comment["parent_author"],
                        c_comment["parent_permlink"])
                    c_parent = Comment(parent_identifier,
                                       blockchain_instance=self.hive)
                    for v in c_parent.get_votes(raw_data=True):
                        if self.token_config[token]["token_account"] == v[
                                "voter"]:
                            already_voted = True
                else:
                    for v in c_comment.get_votes(raw_data=True):
                        if self.token_config[token]["token_account"] == v[
                                "voter"]:
                            already_voted = True
                if already_voted:
                    continue

                already_replied = None
                cnt = 0
                if self.token_config[token]["usage_upvote_percentage"] == 0:

                    while already_replied is None and cnt < 5:
                        cnt += 1
                        try:
                            already_replied = False
                            for r in c_comment.get_all_replies():
                                if r["author"] == self.token_config[token][
                                        "token_account"]:
                                    already_replied = True
                        except:
                            already_replied = None
                            self.hive.rpc.next()
                    if already_replied is None:
                        already_replied = False
                        for r in c_comment.get_all_replies():
                            if r["author"] == self.token_config[token][
                                    "token_account"]:
                                already_replied = True

                    if already_replied:
                        continue

                muting_acc = Account(self.token_config[token]["token_account"],
                                     blockchain_instance=self.hive)
                blocked_accounts = muting_acc.get_mutings()
                if c_comment["author"] in blocked_accounts:
                    logger.info("%s is blocked" % c_comment["author"])
                    continue

                # Load bot token balance
                bot_wallet = Wallet(self.token_config[token]["token_account"],
                                    blockchain_instance=self.hive)
                symbol = bot_wallet.get_token(
                    self.token_config[token]["symbol"])

                # parse amount when user_can_specify_amount is true
                amount = self.token_config[token]["default_amount"]
                if self.token_config[token]["user_can_specify_amount"]:
                    start_index = c_comment["body"].find(
                        self.token_config[token]["comment_command"])
                    stop_index = c_comment["body"][start_index:].find("\n")
                    if stop_index >= 0:
                        command = c_comment["body"][start_index +
                                                    1:start_index + stop_index]
                    else:
                        command = c_comment["body"][start_index + 1:]

                    command_args = command.replace('  ', ' ').split(" ")[1:]

                    if len(command_args) > 0:
                        try:
                            amount = float(command_args[0])
                        except Exception as e:
                            exc_type, exc_obj, exc_tb = sys.exc_info()
                            fname = os.path.split(
                                exc_tb.tb_frame.f_code.co_filename)[1]
                            logger.warn("%s - %s - %s" %
                                        (str(exc_type), str(fname),
                                         str(exc_tb.tb_lineno)))
                            logger.info("Could not parse amount")
                    if self.token_config[token][
                            "maximum_amount_per_comment"] and amount > self.token_config[
                                token]["maximum_amount_per_comment"]:
                        amount = self.token_config[token][
                            "maximum_amount_per_comment"]

                if not self.config["no_broadcast"] and self.hive.wallet.locked(
                ):
                    self.hive.wallet.unlock(self.config["wallet_password"])

                self.log_data["new_commands"] += 1
                wallet = Wallet(c_comment["author"],
                                blockchain_instance=self.hive)
                token_in_wallet = wallet.get_token(
                    self.token_config[token]["symbol"])
                balance = 0
                if token_in_wallet is not None:
                    logger.info(token_in_wallet)
                    if self.token_config[token]["count_only_staked_token"]:
                        balance = 0
                    else:
                        balance = float(token_in_wallet["balance"])
                    if "stake" in token_in_wallet:
                        balance += float(token_in_wallet['stake'])
                    if 'delegationsIn' in token_in_wallet and float(
                            token_in_wallet['delegationsIn']) > 0:
                        balance += float(token_in_wallet['delegationsIn'])
                    if 'pendingUnstake' in token_in_wallet and float(
                            token_in_wallet['pendingUnstake']) > 0:
                        balance += float(token_in_wallet['pendingUnstake'])

                    if balance > self.token_config[token][
                            "min_token_in_wallet"]:
                        if self.token_config[token][
                                "token_in_wallet_for_each_outgoing_token"] > 0:
                            max_token_to_give = int(
                                balance / self.token_config[token]
                                ["token_in_wallet_for_each_outgoing_token"])
                        else:
                            max_token_to_give = self.token_config[token][
                                "maximum_amount_per_comment"]
                    else:
                        max_token_to_give = 0
                else:
                    max_token_to_give = 0
                logger.info("token to give for %s: %f" %
                            (c_comment["author"], max_token_to_give))

                db_data = read_data(self.data_file)
                if "accounts" in db_data and c_comment["author"] in db_data[
                        "accounts"] and token in db_data["accounts"][
                            c_comment["author"]]:
                    if db_data["accounts"][c_comment["author"]][token][
                            "last_date"] == date.today(
                            ) and self.token_config[token][
                                "token_in_wallet_for_each_outgoing_token"] > 0:
                        max_token_to_give = max_token_to_give - db_data[
                            "accounts"][c_comment["author"]][token]["amount"]

                if amount > max_token_to_give:
                    amount = max_token_to_give
                if amount > self.token_config[token][
                        "maximum_amount_per_comment"]:
                    amount = self.token_config[token][
                        "maximum_amount_per_comment"]

                if token_in_wallet is None or balance < self.token_config[
                        token]["min_token_in_wallet"]:
                    reply_body = self.token_config[token]["fail_reply_body"]
                elif max_token_to_give < 1:
                    reply_body = self.token_config[token][
                        "no_token_left_for_today"]
                elif c_comment["parent_author"] == c_comment["author"]:
                    reply_body = "You cannot sent token to yourself."
                elif float(symbol["balance"]) < amount:
                    reply_body = self.token_config[token]["no_token_left_body"]
                else:
                    if "{}" in self.token_config[token]["sucess_reply_body"]:
                        reply_body = (self.token_config[token]
                                      ["sucess_reply_body"]).format(
                                          c_comment["parent_author"])
                    else:
                        reply_body = self.token_config[token][
                            "sucess_reply_body"]
                    if "{}" in self.token_config[token]["token_memo"]:
                        token_memo = (
                            self.token_config[token]["token_memo"]).format(
                                c_comment["author"])
                    else:
                        token_memo = self.token_config[token]["token_memo"]

                    sendwallet = Wallet(
                        self.token_config[token]["token_account"],
                        blockchain_instance=self.hive)

                    try:
                        logger.info(
                            "Sending %.2f %s to %s" %
                            (amount, self.token_config[token]["symbol"],
                             c_comment["parent_author"]))
                        sendwallet.transfer(c_comment["parent_author"], amount,
                                            self.token_config[token]["symbol"],
                                            token_memo)

                        if "accounts" in db_data:
                            accounts = db_data["accounts"]
                        else:
                            accounts = {}
                        if c_comment["author"] not in accounts:
                            accounts[c_comment["author"]] = {}
                            accounts[c_comment["author"]][token] = {
                                "last_date": date.today(),
                                "n_comments": 1,
                                "amount": amount
                            }
                        elif token not in accounts[c_comment["author"]]:
                            accounts[c_comment["author"]][token] = {
                                "last_date": date.today(),
                                "n_comments": 1,
                                "amount": amount
                            }
                        else:
                            if accounts[c_comment["author"]][token][
                                    "last_date"] < date.today():
                                accounts[c_comment["author"]][token] = {
                                    "last_date": date.today(),
                                    "n_comments": 1,
                                    "amount": amount
                                }
                            else:
                                accounts[c_comment["author"]][token][
                                    "n_comments"] += 1
                                accounts[c_comment["author"]][token][
                                    "amount"] += amount

                        store_data(self.data_file, "accounts", accounts)
                        logger.info(
                            "%s - %s" %
                            (c_comment["author"],
                             str(accounts[c_comment["author"]][token])))

                    except Exception as e:
                        exc_type, exc_obj, exc_tb = sys.exc_info()
                        fname = os.path.split(
                            exc_tb.tb_frame.f_code.co_filename)[1]
                        logger.warn(
                            "%s - %s - %s" %
                            (str(exc_type), str(fname), str(exc_tb.tb_lineno)))
                        logger.warn("Could not send %s token" %
                                    self.token_config[token]["symbol"])
                        continue

                reply_identifier = construct_authorperm(
                    c_comment["parent_author"], c_comment["parent_permlink"])
                if self.config["no_broadcast"]:
                    logger.info("%s" % reply_body)
                else:
                    try:
                        self.hive.post(
                            "",
                            reply_body,
                            author=self.token_config[token]["token_account"],
                            reply_identifier=reply_identifier)
                        if self.token_config[token][
                                "usage_upvote_percentage"] <= 0:
                            time.sleep(5)
                            self.hive.post(
                                "",
                                "Command accepted!",
                                author=self.token_config[token]
                                ["token_account"],
                                reply_identifier=c_comment["authorperm"])
                    except Exception as e:
                        exc_type, exc_obj, exc_tb = sys.exc_info()
                        fname = os.path.split(
                            exc_tb.tb_frame.f_code.co_filename)[1]
                        logger.warn(
                            "%s - %s - %s" %
                            (str(exc_type), str(fname), str(exc_tb.tb_lineno)))
                        logger.warn("Could not reply to post")
                        continue
                    if self.token_config[token]["usage_upvote_percentage"] > 0:
                        time.sleep(5)
                        upvote_percentge = self.token_config[token][
                            "usage_upvote_percentage"]
                        if self.token_config[token]["scale_upvote_weight"]:
                            upvote_percentge = upvote_percentge * amount / self.token_config[
                                token]["maximum_amount_per_comment"]
                        print("Upvote with %.2f %%" % upvote_percentge)
                        if self.token_config[token]["upvote_token_receiver"]:
                            if c_parent is None:
                                c_parent = Comment(
                                    parent_identifier,
                                    blockchain_instance=self.hive)
                            try:
                                c_parent.upvote(upvote_percentge,
                                                voter=self.token_config[token]
                                                ["token_account"])
                            except Exception as e:
                                exc_type, exc_obj, exc_tb = sys.exc_info()
                                fname = os.path.split(
                                    exc_tb.tb_frame.f_code.co_filename)[1]
                                logger.warn("%s - %s - %s" %
                                            (str(exc_type), str(fname),
                                             str(exc_tb.tb_lineno)))
                                logger.warn("Could not upvote comment")
                        else:
                            try:
                                c_comment.upvote(upvote_percentge,
                                                 voter=self.token_config[token]
                                                 ["token_account"])
                            except Exception as e:
                                exc_type, exc_obj, exc_tb = sys.exc_info()
                                fname = os.path.split(
                                    exc_tb.tb_frame.f_code.co_filename)[1]
                                logger.warn("%s - %s - %s" %
                                            (str(exc_type), str(fname),
                                             str(exc_tb.tb_lineno)))
                                logger.warn("Could not upvote comment")

                time.sleep(4)
        return last_block_num
Example #30
0
 if int(vote["rshares"]) == 0:
     continue
 if (addTzInfo(datetime.utcnow()) - (vote["time"])
     ).total_seconds() / 60 / 60 / 24 <= 7:
     continue
 if vote["voter"] not in member_data:
     continue
 if authorperm in comments_transfer and stm.rshares_to_sbd(
         int(vote["rshares"])) >= 0.05:
     try:
         if cnt3 % 10 == 0:
             print("%d/%d votes" %
                   (cnt3, len(c["active_votes"])))
         block_num = b.get_estimated_block_num(
             vote["time"])
         current_block_num = b.get_current_block_num()
         transaction = None
         block_search_list = [
             0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5
         ]
         block_cnt = 0
         while transaction is None and block_cnt < len(
                 block_search_list):
             if block_num + block_search_list[
                     block_cnt] > current_block_num:
                 block_cnt += 1
                 continue
             block = Block(block_num +
                           block_search_list[block_cnt],
                           steem_instance=stm)
             for tt in block.transactions: