Skip to content
Permalink
Browse files

BANANO-ify and more

- Rewrite DB layer to use peewee ORM with a pooled postgres database
- Use eventlet green-threads instead of pre-fork strategy for concurrency
- Some other minor things, like adding use_peers to work_generate
  • Loading branch information...
bbedward committed Feb 19, 2019
1 parent 327e294 commit 4ec2a1cf97b0d26ab6f41dc6c141ebf848f60d05
Showing with 356 additions and 528 deletions.
  1. +11 −9 README.md
  2. +37 −44 modules/currency.py
  3. +47 −187 modules/db.py
  4. +178 −220 modules/orchestration.py
  5. +14 −14 modules/social.py
  6. +4 −3 requirements.pip
  7. +15 −0 tipbot.service
  8. +50 −51 webhooks.py
@@ -1,17 +1,19 @@
NOS Telegram Tip Bot
# BANANO Telegram Tip Bot

Commands

Thank you for using my services @NOSTipBot! Below is a list of commands, and a description of how you can interact with me:
- .tip
- .help
- .register
- .account
- .withdraw

• !help: The NOSTipBot will respond to your DM with a list of commands and their functions. If you forget something, use this to get a hint of how to do it!n
# Install

• !register: Creates a fresh NOS (XNOS) account address specifically for you. This is used to store your tips. Make sure to withdraw to a private wallet, as the tip bot is not meant to be a long term storage device for NOS (XNOS).
`cp config/example_config.ini config/webhooks.ini`

• !balance: This shows you how much funds are in your your account.
Specify postgres user/schema/port/host

• !tip: Tips are sent directly to @username on telegram. Tag @NOSTipBot and mention !tip <amount> <@username>. EXAMPLE: @NOSTipBot !tip 1 @user will send a 1 NOS (XNOS) tip to another user.
Copy tipbot.service example to systemd

• !account: Returns the account number. You can use this to deposit more NOS (XNOS) to tip from your personal wallet.

• !withdraw: Proper usage is !withdraw nos_12345. This will send the full balance of your tip account to another external NOS (XNOS) account. Optional: You can include an amount to withdraw by sending !withdraw <amount> <address>. Example: !withdraw 1 nos_123 would withdraw 1 Nos to account nos_123
Run with systemd
@@ -8,7 +8,8 @@
import nano
import requests

from . import db, social
import db
import social

# Read config and parse constants
config = configparser.ConfigParser()
@@ -20,23 +21,23 @@

# Connect to Nano node
rpc = nano.rpc.Client(NODE_IP)
raw_denominator = 10**10
raw_denominator = 10**29


def receive_pending(sender_account):
"""
Check to see if the account has any pending blocks and process them
"""
try:
logging.info("{}: in receive pending".format(datetime.now()))
logging.info("{}: in receive pending".format(datetime.utcnow()))
pending_blocks = rpc.pending(account='{}'.format(sender_account))
logging.info("pending blocks: {}".format(pending_blocks))
if len(pending_blocks) > 0:
for block in pending_blocks:
work = get_pow(sender_account)
if work == '':
logging.info("{}: processing without pow".format(
datetime.now()))
datetime.utcnow()))
receive_data = {
'action': "receive",
'wallet': WALLET,
@@ -45,7 +46,7 @@ def receive_pending(sender_account):
}
else:
logging.info("{}: processing with pow".format(
datetime.now()))
datetime.utcnow()))
receive_data = {
'action': "receive",
'wallet': WALLET,
@@ -56,10 +57,10 @@ def receive_pending(sender_account):
receive_json = json.dumps(receive_data)
requests.post('{}'.format(NODE_IP), data=receive_json)
logging.info("{}: block {} received".format(
datetime.now(), block))
datetime.utcnow(), block))

else:
logging.info('{}: No blocks to receive.'.format(datetime.now()))
logging.info('{}: No blocks to receive.'.format(datetime.utcnow()))

except Exception as e:
logging.info("Receive Pending Error: {}".format(e))
@@ -72,25 +73,25 @@ def get_pow(sender_account):
"""
Retrieves the frontier (hash of previous transaction) of the provided account and generates work for the next block.
"""
logging.info("{}: in get_pow".format(datetime.now()))
logging.info("{}: in get_pow".format(datetime.utcnow()))
try:
account_frontiers = rpc.accounts_frontiers([sender_account])
frontier_hash = account_frontiers[sender_account]
except Exception as e:
logging.info("{}: Error checking frontier: {}".format(
datetime.now(), e))
datetime.utcnow(), e))
return ''
logging.info("account_frontiers: {}".format(account_frontiers))

work = ''
logging.info("{}: hash: {}".format(datetime.now(), frontier_hash))
logging.info("{}: hash: {}".format(datetime.utcnow(), frontier_hash))
while work == '':
try:
work = rpc.work_generate(frontier_hash)
logging.info("{}: Work generated: {}".format(datetime.now(), work))
work = rpc.work_generate(frontier_hash, use_peers=True)
logging.info("{}: Work generated: {}".format(datetime.utcnow(), work))
except Exception as e:
logging.info("{}: ERROR GENERATING WORK: {}".format(
datetime.now(), e))
datetime.utcnow(), e))
pass

return work
@@ -101,42 +102,36 @@ def send_tip(message, users_to_tip, tip_index):
Process tip for specified user
"""
logging.info("{}: sending tip to {}".format(
datetime.now(), users_to_tip[tip_index]['receiver_screen_name']))
datetime.utcnow(), users_to_tip[tip_index]['receiver_screen_name']))
if str(users_to_tip[tip_index]['receiver_id']) == str(
message['sender_id']):
self_tip_text = "Self tipping is not allowed. Please use this bot to spread the NOS to other users!"
self_tip_text = "Self tipping is not allowed. Please use this bot to tip BANANO to other users!"
social.send_reply(message, self_tip_text)

logging.info("{}: User tried to tip themself").format(datetime.now())
logging.info("{}: User tried to tip themself").format(datetime.utcnow())
return

# Check if the receiver has an account
receiver_account_get = "SELECT account FROM users where user_id = %s"
arguments = (int(users_to_tip[tip_index]['receiver_id']))
receiver_account_data = db.get_db_data(receiver_account_get, arguments)


# If they don't, create an account for them
if not receiver_account_data:
try:
user = db.User.select().where(db.User.user_id == int(users_to_tip[tip_index]['receiver_id'])).get()
users_to_tip[tip_index]['receiver_account'] = user.account
except db.User.DoesNotExist:
# If they don't, create an account for them
users_to_tip[tip_index]['receiver_account'] = rpc.account_create(
wallet="{}".format(WALLET), work=True)
create_receiver_account = (
"INSERT INTO users (user_id, user_name, account, register) "
"VALUES({}, '{}', '{}',0)".format(
users_to_tip[tip_index]['receiver_id'],
users_to_tip[tip_index]['receiver_screen_name'],
users_to_tip[tip_index]['receiver_account']))
db.set_db_data(create_receiver_account)
user = db.User(
user_id = int(users_to_tip[tip_index]['receiver_id']),
user_name = users_to_tip[tip_index]['receiver_screen_name'],
account = users_to_tip[tip_index]['receiver_account'],
register=0
)
user.save()
logging.info(
"{}: Sender sent to a new receiving account. Created account {}".
format(datetime.now(),
format(datetime.utcnow(),
users_to_tip[tip_index]['receiver_account']))

else:
users_to_tip[tip_index]['receiver_account'] = receiver_account_data[0][
0]

# Send the tip

message['tip_id'] = "{}{}".format(message['id'], tip_index)

work = get_pow(message['sender_account'])
@@ -185,19 +180,17 @@ def send_tip(message, users_to_tip, tip_index):

# Send a DM to the receiver
receiver_tip_text = (
"@{} just sent you a {} NOS tip! Reply to this DM with !balance to see your new balance. If you have not "
"registered an account, send a reply with !register to get started, or !help to see a list of "
"commands! Learn more about NOS (XNOS) & Nollar at https://nos.cash/"
.format(message['sender_screen_name'], message['tip_amount_text'],
users_to_tip[tip_index]['balance']))
"@{0} just sent you a {1} BANANO tip! Reply to this DM with .balance to see your new balance. If you have not "
"registered an account, send a reply with .register to get started, or .help to see a list of "
"commands! Learn more about BANANO at https://banano.cc"
.format(message['sender_screen_name'], message['tip_amount_text']))
social.send_dm(users_to_tip[tip_index]['receiver_id'],
receiver_tip_text)

except Exception as e:
logging.info(
"{}: ERROR IN RECEIVING NEW TIP - POSSIBLE NEW ACCOUNT NOT REGISTERED WITH DPOW: {}"
.format(datetime.now(), e))
.format(datetime.utcnow(), e))

logging.info("{}: tip sent to {} via hash {}".format(
datetime.now(), users_to_tip[tip_index]['receiver_screen_name'],
datetime.utcnow(), users_to_tip[tip_index]['receiver_screen_name'],
message['send_hash']))
Oops, something went wrong.

0 comments on commit 4ec2a1c

Please sign in to comment.
You can’t perform that action at this time.