def submit_events(): sql = "select id from event where start_time < NOW() and prepare_time < NOW() and prepare_time > 0 and submit_time = 0" c = libmysql.db.cursor() c.execute( sql ) rows = c.fetchall() for row in rows: event = Event() event.load(row[0]) govobj = GovernanceObject() print event.get_id() govobj.load(event.get_id()) hash = govobj.get_field("object_fee_tx") print "# SUBMIT PREPARED EVENTS FOR DASH NETWORK" print print " -- cmd : ", govobj.get_submit_command() print print " -- executing event ... getting fee_tx hash" if misc.is_hash(hash): tx = dashd.CTransaction() if tx.load(hash): print " -- confirmations: ", tx.get_confirmations() if tx.get_confirmations() >= CONFIRMATIONS_REQUIRED: event.set_submitted() print " -- executing event ... getting fee_tx hash" result = dashd.rpc_command(govobj.get_submit_command()) if misc.is_hash(result): print " -- got result", result govobj.update_field("object_hash", result) event.save() govobj.save() libmysql.db.commit() return 1 else: print " -- got error", result else: print " -- waiting for confirmation" return 0
def prepare_events(): sql = "select id from event where start_time < NOW() and error_time = 0 and prepare_time = 0" c = libmysql.db.cursor() c.execute( sql ) rows = c.fetchall() for row in rows: event = Event() event.load(row[0]) govobj = GovernanceObject() govobj.load(event.get_id()) print "# PREPARING EVENTS FOR DASH NETWORK" print print " -- cmd : ", govobj.get_prepare_command() print result = dashd.rpc_command(govobj.get_prepare_command()) print " -- executing event ... getting fee_tx hash" # todo: what should it do incase of error? if misc.is_hash(result): hashtx = misc.clean_hash(result) print " -- got hash:", hashtx govobj.update_field("object_fee_tx", hashtx) govobj.save() event.update_field("prepare_time", misc.get_epoch()) event.save() libmysql.db.commit() return 1 else: print " -- got error:", result event.update_field("error_time", misc.get_epoch()) event.save() # separately update event error message event.update_error_message(result) libmysql.db.commit() return 0
def do_proposal(self, arg): 'proposal --create --proposal_name="sb-test" --description_url="www.dashwhale.org/p/sb-test" --start_date="2016/8/1" --end_date="2017/1/1" --payment_address="ydE7B1A7htNwSTvvER6xBdgpKZqNDbbEhPydE7B1A7htNwSTvvER6xBdgpKZqNDbbEhP" --payment_amount="23"' parser = argparse.ArgumentParser(description='Create a dash proposal') # desired action parser.add_argument('-c', '--create', help="create", action='store_true') # object identity (existentially... what does it mean to be a pubkey?) parser.add_argument('-k', '--pubkey', help='your public key for this username (only required for --create)') # meta data (create or amend) parser.add_argument('-p', '--proposal_name', help='the proposal name (must be unique)') parser.add_argument('-d', '--description_url', help='your proposals url where a description of the project can be found') parser.add_argument('-s', '--start_date', help='starting data, must be the first of the month. Example : 2017/1/1') parser.add_argument('-e', '--end_date', help='ending data, must be the first of the month. Example : 2017/6/1') parser.add_argument('-x', '--payment_address', help='the payment address where you wish to receive the funds') parser.add_argument('-a', '--payment_amount', help='how much to send in each payment to the payment address') # process args = None try: args = parser.parse_args(parse(arg)) except: pass if not args: return ### ------ CREATE METHOD -------- #### if args.create: #--create --revision=1 --pubkey=XPubkey --username="******" if not args.proposal_name: print "proposal creation requires a proposal name, use --proposal_name" return if not args.description_url: print "proposal creation requires a description url, use --description_url" return if not args.start_date: print "start creation requires a start date, use --start_date" return if not args.end_date: print "end creation requires a end date, use --end_date" return if not args.payment_address: print "payment creation requires a valid base58 payment address, use --payment_address" return if not args.payment_amount: print "payment creation requires a valid payment amount, use --payment_amount" return ### ---- CONVERT AND CHECK EPOCHS ----- start_epoch = 0 end_epoch = 0 try: start_epoch = datetime.strptime(args.start_date, '"%d/%m/%y"').strftime('%s') end_epoch = datetime.strptime(args.end_date, '"%d/%m/%y"').strftime('%s') except: try: start_epoch = datetime.strptime(args.start_date, '"%Y/%m/%d"').strftime('%s') end_epoch = datetime.strptime(args.end_date, '"%Y/%m/%d"').strftime('%s') except: pass if start_epoch == 0 or end_epoch == 0: print "start or end date has invalid format, YYYY/MM/DD or DD/MM/YY is required"; return ### ---- CHECK NAME UNIQUENESS ----- if GovernanceObjectMananger.object_with_name_exists(args.proposal_name): print "governance object with that name already exists" return fee_tx = CTransaction() newObj = GovernanceObject() newObj.create_new(parent, args.proposal_name, govtypes.proposal, govtypes.FIRST_REVISION, fee_tx) last_id = newObj.save() print last_id if last_id != None: # ADD OUR PROPOSAL AS A SUB-OBJECT WITHIN GOVERNANCE OBJECT c = Proposal() c.set_field("governance_object_id", last_id) c.set_field("type", govtypes.proposal) c.set_field("proposal_name", args.proposal_name) c.set_field("description_url", args.description_url) c.set_field("start_epoch", start_epoch) c.set_field("end_epoch", end_epoch) c.set_field("payment_address", args.payment_address) c.set_field("payment_amount", args.payment_amount) # APPEND TO GOVERNANCE OBJECT newObj.add_subclass("proposal", c) newObj.save() # CREATE EVENT TO TALK TO DASHD / PREPARE / SUBMIT OBJECT event = Event() event.create_new(last_id) event.save() libmysql.db.commit() print "event queued successfully" else: print "error:", newObj.last_error() # abort mysql commit return ### ------- ELSE PRINT HELP --------------- ### parser.print_help()
def do_superblock(self, arg): 'superblock --create --event_block_height="28224" --payments="yLipDagwb1gM15RaUq3hpcaTxzDsFsSy9a=100"' 'superblock --create --event_date="2017/1/1" --payments="Addr1=amount,Addr2=amount,Addr3=amount"' parser = argparse.ArgumentParser(description='Create a dash proposal') # desired action parser.add_argument('-c', '--create', help="create", action='store_true') # meta data (create or amend) parser.add_argument('-p', '--payments', help='the payments desired in the superblock, serialized as a list. example: {"Addr1": amount,"Addr2": amount}') parser.add_argument('-b', '--event_block_height', help='block height to issue superblock') # process args = None try: args = parser.parse_args(parse(arg)) except: pass if not args: return ### ------ CREATE METHOD -------- #### if args.create: #--create --revision=1 --pubkey=XPubkey --username="******" if not args.payments: print "superblock creation requires a payment descriptions, use --payments" return if not args.event_block_height: print "superblock creation requires a event_block_height, use --event_block_height" return ### ---- CONVERT AND CHECK EPOCHS ----- payments = misc.normalize(args.payments).split(",") if len(payments) > 0: pass # COMPILE LIST OF ADDRESSES AND AMOUNTS list_addr = [] list_amount = [] for payment in payments: print payment addr,amount = payment.split("=") list_addr.append(addr) list_amount.append(amount) print list_amount print list_addr # CREATE NAME ACCORDING TO STARTING DATE (NON-UNIQUE IS NOT AN ATTACK) superblock_name = "sb" + str(random.randint(1000000, 9999999)) # DOES THIS ALREADY EXIST? if GovernanceObjectMananger.object_with_name_exists(superblock_name): print "governance object with that name already exists" return event_block_height = misc.normalize(args.event_block_height); print event_block_height fee_tx = CTransaction() newObj = GovernanceObject() newObj.create_new(parent, superblock_name, govtypes.trigger, govtypes.FIRST_REVISION, fee_tx) last_id = newObj.save() print last_id if last_id != None: # ADD OUR PROPOSAL AS A SUB-OBJECT WITHIN GOVERNANCE OBJECT c = Superblock() c.set_field("governance_object_id", last_id) c.set_field("type", govtypes.trigger) c.set_field("subtype", "superblock") c.set_field("superblock_name", superblock_name) c.set_field("event_block_height", event_block_height) c.set_field("payment_addresses", "|".join(list_addr)) c.set_field("payment_amounts", "|".join(list_amount)) # APPEND TO GOVERNANCE OBJECT newObj.add_subclass("trigger", c) newObj.save() # CREATE EVENT TO TALK TO DASHD / PREPARE / SUBMIT OBJECT event = Event() event.create_new(last_id) event.save() libmysql.db.commit() print "event queued successfully" else: print "error:", newObj.last_error() # abort mysql commit return ### ------- ELSE PRINT HELP --------------- ### parser.print_help()
import crontab import cmd, sys import govtypes import random import json from datetime import datetime, date, time from governance import GovernanceObject, GovernanceObjectMananger, Setting, Event from classes import Proposal, Superblock from dashd import CTransaction # Enable only for testing: crontab.CONFIRMATIONS_REQUIRED = 1 parent = GovernanceObject() parent.init() db = libmysql.connect(config.hostname, config.username, config.password, config.database) commands = {} """ Sentinel - v1 -------------------------------- - this is an exact copy of our existing functionality, just reimplemented in python using sentinel old commands: mnbudget prepare beer-reimbursement2 www.dashwhale.org/p/beer-reimbursement2 1 481864 XfoGXXFJtobHvjwfszWnbMNZCBAHJWeN6G 50
#!/usr/bin/env python import json import dashd import sys sys.path.append("lib") from governance import GovernanceObject """ - this script is ran ~2.5/minutes and processes updates to the governance system """ difflist = json.loads(dashd.cmd("governance diff")) for item in difflist: obj = GovernanceObject(item) obj.save() if obj.is_valid(): obj.vote(VOTE_ACTION_VALID, VOTE_OUTCOME_NO) pass
def do_proposal(self, arg): 'proposal --create --proposal_name="sb-test" --description_url="www.dashwhale.org/p/sb-test" --start_date="2016/8/1" --end_date="2017/1/1" --payment_address="ydE7B1A7htNwSTvvER6xBdgpKZqNDbbEhPydE7B1A7htNwSTvvER6xBdgpKZqNDbbEhP" --payment_amount="23"' parser = argparse.ArgumentParser(description='Create a dash proposal') # desired action parser.add_argument('-c', '--create', help="create", action='store_true') # object identity (existentially... what does it mean to be a pubkey?) parser.add_argument( '-k', '--pubkey', help= 'your public key for this username (only required for --create)') # meta data (create or amend) parser.add_argument('-p', '--proposal_name', help='the proposal name (must be unique)') parser.add_argument( '-d', '--description_url', help= 'your proposals url where a description of the project can be found' ) parser.add_argument( '-s', '--start_date', help= 'starting data, must be the first of the month. Example : 2017/1/1' ) parser.add_argument( '-e', '--end_date', help= 'ending data, must be the first of the month. Example : 2017/6/1') parser.add_argument( '-x', '--payment_address', help='the payment address where you wish to receive the funds') parser.add_argument( '-a', '--payment_amount', help='how much to send in each payment to the payment address') # process args = None try: args = parser.parse_args(parse(arg)) except: pass if not args: return ### ------ CREATE METHOD -------- #### if args.create: #--create --revision=1 --pubkey=XPubkey --username="******" if not args.proposal_name: print "proposal creation requires a proposal name, use --proposal_name" return if not args.description_url: print "proposal creation requires a description url, use --description_url" return if not args.start_date: print "start creation requires a start date, use --start_date" return if not args.end_date: print "end creation requires a end date, use --end_date" return if not args.payment_address: print "payment creation requires a valid base58 payment address, use --payment_address" return if not args.payment_amount: print "payment creation requires a valid payment amount, use --payment_amount" return ### ---- CONVERT AND CHECK EPOCHS ----- start_epoch = 0 end_epoch = 0 try: start_epoch = datetime.strptime(args.start_date, '"%d/%m/%y"').strftime('%s') end_epoch = datetime.strptime(args.end_date, '"%d/%m/%y"').strftime('%s') except: try: start_epoch = datetime.strptime( args.start_date, '"%Y/%m/%d"').strftime('%s') end_epoch = datetime.strptime(args.end_date, '"%Y/%m/%d"').strftime('%s') except: pass if start_epoch == 0 or end_epoch == 0: print "start or end date has invalid format, YYYY/MM/DD or DD/MM/YY is required" return ### ---- CHECK NAME UNIQUENESS ----- if GovernanceObjectMananger.object_with_name_exists( args.proposal_name): print "governance object with that name already exists" return fee_tx = CTransaction() newObj = GovernanceObject() newObj.create_new(parent, args.proposal_name, govtypes.proposal, govtypes.FIRST_REVISION, fee_tx) last_id = newObj.save() print last_id if last_id != None: # ADD OUR PROPOSAL AS A SUB-OBJECT WITHIN GOVERNANCE OBJECT c = Proposal() c.set_field("governance_object_id", last_id) c.set_field("type", govtypes.proposal) c.set_field("proposal_name", args.proposal_name) c.set_field("description_url", args.description_url) c.set_field("start_epoch", start_epoch) c.set_field("end_epoch", end_epoch) c.set_field("payment_address", args.payment_address) c.set_field("payment_amount", args.payment_amount) # APPEND TO GOVERNANCE OBJECT newObj.add_subclass("proposal", c) newObj.save() # CREATE EVENT TO TALK TO DASHD / PREPARE / SUBMIT OBJECT event = Event() event.create_new(last_id) event.save() libmysql.db.commit() print "event queued successfully" else: print "error:", newObj.last_error() # abort mysql commit return ### ------- ELSE PRINT HELP --------------- ### parser.print_help()
def do_superblock(self, arg): 'superblock --create --event_block_height="28224" --payments="yLipDagwb1gM15RaUq3hpcaTxzDsFsSy9a=100"' 'superblock --create --event_date="2017/1/1" --payments="Addr1=amount,Addr2=amount,Addr3=amount"' parser = argparse.ArgumentParser(description='Create a dash proposal') # desired action parser.add_argument('-c', '--create', help="create", action='store_true') # meta data (create or amend) parser.add_argument( '-p', '--payments', help= 'the payments desired in the superblock, serialized as a list. example: {"Addr1": amount,"Addr2": amount}' ) parser.add_argument('-b', '--event_block_height', help='block height to issue superblock') # process args = None try: args = parser.parse_args(parse(arg)) except: pass if not args: return ### ------ CREATE METHOD -------- #### if args.create: #--create --revision=1 --pubkey=XPubkey --username="******" if not args.payments: print "superblock creation requires a payment descriptions, use --payments" return if not args.event_block_height: print "superblock creation requires a event_block_height, use --event_block_height" return ### ---- CONVERT AND CHECK EPOCHS ----- payments = misc.normalize(args.payments).split(",") if len(payments) > 0: pass # COMPILE LIST OF ADDRESSES AND AMOUNTS list_addr = [] list_amount = [] for payment in payments: print payment addr, amount = payment.split("=") list_addr.append(addr) list_amount.append(amount) print list_amount print list_addr # CREATE NAME ACCORDING TO STARTING DATE (NON-UNIQUE IS NOT AN ATTACK) superblock_name = "sb" + str(random.randint(1000000, 9999999)) # DOES THIS ALREADY EXIST? if GovernanceObjectMananger.object_with_name_exists( superblock_name): print "governance object with that name already exists" return event_block_height = misc.normalize(args.event_block_height) print event_block_height fee_tx = CTransaction() newObj = GovernanceObject() newObj.create_new(parent, superblock_name, govtypes.trigger, govtypes.FIRST_REVISION, fee_tx) last_id = newObj.save() print last_id if last_id != None: # ADD OUR PROPOSAL AS A SUB-OBJECT WITHIN GOVERNANCE OBJECT c = Superblock() c.set_field("governance_object_id", last_id) c.set_field("type", govtypes.trigger) c.set_field("subtype", "superblock") c.set_field("superblock_name", superblock_name) c.set_field("event_block_height", event_block_height) c.set_field("payment_addresses", "|".join(list_addr)) c.set_field("payment_amounts", "|".join(list_amount)) # APPEND TO GOVERNANCE OBJECT newObj.add_subclass("trigger", c) newObj.save() # CREATE EVENT TO TALK TO DASHD / PREPARE / SUBMIT OBJECT event = Event() event.create_new(last_id) event.save() libmysql.db.commit() print "event queued successfully" else: print "error:", newObj.last_error() # abort mysql commit return ### ------- ELSE PRINT HELP --------------- ### parser.print_help()
import misc import libmysql import config import crontab import cmd, sys import govtypes import random import json from datetime import datetime, date, time from governance import GovernanceObject, GovernanceObjectMananger, Setting, Event from classes import Proposal, Superblock from dashd import CTransaction parent = GovernanceObject() parent.init() db = libmysql.connect(config.hostname, config.username, config.password, config.database) commands = {} """ Sentinel - v1 -------------------------------- - this is an exact copy of our existing functionality, just reimplemented in python using sentinel old commands: mnbudget prepare beer-reimbursement2 www.dashwhale.org/p/beer-reimbursement2 1 481864 XfoGXXFJtobHvjwfszWnbMNZCBAHJWeN6G 50
def submit_events(): sql = "select id from event where start_time < NOW() and prepare_time < NOW() and submit_time = 0 limit 1" libmysql.db.query(sql) res = libmysql.db.store_result() row = res.fetch_row() if row: event = Event() event.load(row[0]) govobj = GovernanceObject() print event.get_id() govobj.load(event.get_id()) hash = govobj.get_field("object_fee_tx") print "# SUBMIT PREPARED EVENTS FOR DASH NETWORK" print print " -- cmd : ", govobj.get_submit_command() print print " -- executing event ... getting fee_tx hash" if misc.is_hash(hash): tx = dashd.CTransaction() if tx.load(hash): print " -- confirmations: ", tx.get_confirmations() if tx.get_confirmations() >= 7: event.set_submitted() print " -- executing event ... getting fee_tx hash" result = dashd.rpc_command(govobj.get_submit_command()) if misc.is_hash(result): print " -- got result", result govobj.update_field("object_hash", result) event.save() govobj.save() libmysql.db.commit() return 1 else: print " -- got error", result else: print " -- waiting for confirmation" return 0
def do_test(): parent = GovernanceObject() parent.init() start_epoch = datetime.datetime.strptime(START_DATE, "%Y-%m-%d").strftime('%s') end_epoch = datetime.datetime.strptime(END_DATE, "%Y-%m-%d").strftime('%s') # Step 1 - Create superblock superblock_name = "sb" + str(random.randint(1000000, 9999999)) while GovernanceObjectMananger.object_with_name_exists(superblock_name): superblock_name = "sb" + str(random.randint(1000000, 9999999)) fee_tx = CTransaction() newObj = GovernanceObject() newObj.create_new(parent, superblock_name, govtypes.trigger, govtypes.FIRST_REVISION, fee_tx) last_id = newObj.save() blockCount = int(rpc_command("getblockcount")) event_block_height = "%d" % (blockCount + 10) if last_id is None: raise(Exception("do_test: superblock creation failed")) # ADD OUR PROPOSAL AS A SUB-OBJECT WITHIN GOVERNANCE OBJECT c = Superblock() c.set_field("governance_object_id", last_id) c.set_field("type", govtypes.trigger) c.set_field("subtype", "superblock") c.set_field("superblock_name", superblock_name) c.set_field("event_block_height", event_block_height) c.set_field("payment_addresses", PAYMENT_ADDRESS1) c.set_field("payment_amounts", PAYMENT_AMOUNT1) # APPEND TO GOVERNANCE OBJECT newObj.add_subclass("trigger", c) newObj.save() # CREATE EVENT TO TALK TO DASHD / PREPARE / SUBMIT OBJECT event = Event() event.create_new(last_id) event.save() libmysql.db.commit() # Step 2 - Prepare/submit events do_events() # Step 3 - Create proposal proposal_name = "tprop-" + str(random.randint(1000000, 9999999)) while GovernanceObjectMananger.object_with_name_exists(proposal_name): proposal_name = "test-proposal-" + str(random.randint(1000000, 9999999)) quoted_proposal_name = "'%s'" % ( proposal_name ) fee_tx = CTransaction() newObj = GovernanceObject() newObj.create_new(parent, proposal_name, govtypes.proposal, govtypes.FIRST_REVISION, fee_tx) last_id = newObj.save() if last_id is None: raise(Exception("do_test: proposal creation failed")) c = Proposal() c.set_field("governance_object_id", last_id) c.set_field("type", govtypes.proposal) c.set_field("proposal_name", quoted_proposal_name) c.set_field("description_url", DESCRIPTION_URL) c.set_field("start_epoch", start_epoch) c.set_field("end_epoch", end_epoch) c.set_field("payment_address", PAYMENT_ADDRESS2) c.set_field("payment_amount", PAYMENT_AMOUNT2) # APPEND TO GOVERNANCE OBJECT newObj.add_subclass("proposal", c) newObj.save() # CREATE EVENT TO TALK TO DASHD / PREPARE / SUBMIT OBJECT event = Event() event.create_new(last_id) event.save() libmysql.db.commit() # Step 4 - Prepare/submit events do_events()
def do_test(): parent = GovernanceObject() parent.init() start_epoch = datetime.datetime.strptime(START_DATE, "%Y-%m-%d").strftime('%s') end_epoch = datetime.datetime.strptime(END_DATE, "%Y-%m-%d").strftime('%s') # Step 1 - Create superblock superblock_name = "sb" + str(random.randint(1000000, 9999999)) while GovernanceObjectMananger.object_with_name_exists(superblock_name): superblock_name = "sb" + str(random.randint(1000000, 9999999)) fee_tx = CTransaction() sbObj = GovernanceObject() sbObj.create_new(parent, superblock_name, govtypes.trigger, govtypes.FIRST_REVISION, fee_tx) last_id = sbObj.save() blockCount = int(rpc_command("getblockcount")) event_block_height = "%d" % (blockCount + crontab.CONFIRMATIONS_REQUIRED + 5) if last_id is None: raise (Exception("do_test: superblock creation failed")) # ADD OUR PROPOSAL AS A SUB-OBJECT WITHIN GOVERNANCE OBJECT c = Superblock() c.set_field("governance_object_id", last_id) c.set_field("type", govtypes.trigger) c.set_field("subtype", "superblock") c.set_field("superblock_name", superblock_name) c.set_field("event_block_height", event_block_height) c.set_field("payment_addresses", PAYMENT_ADDRESS1) c.set_field("payment_amounts", PAYMENT_AMOUNT1) # APPEND TO GOVERNANCE OBJECT sbObj.add_subclass("trigger", c) sbObj.save() # CREATE EVENT TO TALK TO DASHD / PREPARE / SUBMIT OBJECT event = Event() event.create_new(last_id) event.save() libmysql.db.commit() # Step 2 - Prepare/submit events print "Before do_events" do_events() print "After do_events" # Step 3 - Vote up the superblock sbObj.load(sbObj.governance_object['id']) print "sbObj.governance_object = %s" % (sbObj.governance_object) print "Getting objectHash" objectHash = sbObj.get_field("object_hash").strip() print "preparing to vote: objectHash = %s, length = %d" % (objectHash, len(objectHash)) if len(objectHash) == 64: vote(objectHash) # Step 4 - Create proposal proposal_name = "tprop-" + str(random.randint(1000000, 9999999)) while GovernanceObjectMananger.object_with_name_exists(proposal_name): proposal_name = "test-proposal-" + str(random.randint( 1000000, 9999999)) quoted_proposal_name = "'%s'" % (proposal_name) fee_tx = CTransaction() newObj = GovernanceObject() newObj.create_new(parent, proposal_name, govtypes.proposal, govtypes.FIRST_REVISION, fee_tx) last_id = newObj.save() if last_id is None: raise (Exception("do_test: proposal creation failed")) c = Proposal() c.set_field("governance_object_id", last_id) c.set_field("type", govtypes.proposal) c.set_field("proposal_name", quoted_proposal_name) c.set_field("description_url", DESCRIPTION_URL) c.set_field("start_epoch", start_epoch) c.set_field("end_epoch", end_epoch) c.set_field("payment_address", PAYMENT_ADDRESS2) c.set_field("payment_amount", PAYMENT_AMOUNT2) # APPEND TO GOVERNANCE OBJECT newObj.add_subclass("proposal", c) newObj.save() # CREATE EVENT TO TALK TO DASHD / PREPARE / SUBMIT OBJECT event = Event() event.create_new(last_id) event.save() libmysql.db.commit() # Step 5 - Prepare/submit events do_events()