Exemple #1
0
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
Exemple #2
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
Exemple #3
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()
Exemple #4
0
    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()
Exemple #5
0
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
Exemple #6
0
#!/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
Exemple #7
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()
Exemple #8
0
    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()
Exemple #9
0
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
Exemple #10
0
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
Exemple #11
0
#!/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
Exemple #12
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()
Exemple #13
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()

    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()