def main(): dashd = DashDaemon.from_dash_conf(config.dash_conf) options = process_args() # check dashd connectivity if not is_dashd_port_open(dashd): print("Cannot connect to dashd. Please ensure dashd is running and the JSONRPC port is open to Sentinel.") return # check dashd sync if not dashd.is_synced(): print("dashd not synced with network! Awaiting full sync before running Sentinel.") return # ensure valid masternode if not dashd.is_masternode(): print("Invalid Masternode Status, cannot continue.") return # register a handler if SENTINEL_DEBUG is set if os.environ.get('SENTINEL_DEBUG', None): import logging logger = logging.getLogger('peewee') logger.setLevel(logging.DEBUG) logger.addHandler(logging.StreamHandler()) if options.bypass: # bypassing scheduler, remove the scheduled event printdbg("--bypass-schedule option used, clearing schedule") Scheduler.clear_schedule() if not Scheduler.is_run_time(): printdbg("Not yet time for an object sync/vote, moving on.") return if not options.bypass: # delay to account for cron minute sync Scheduler.delay() # running now, so remove the scheduled event Scheduler.clear_schedule() # ======================================================================== # general flow: # ======================================================================== # # load "gobject list" rpc command data, sync objects into internal database perform_dashd_object_sync(dashd) # delete old watchdog objects, create a new if necessary watchdog_check(dashd) # auto vote network objects as valid/invalid # check_object_validity(dashd) # create a Superblock if necessary attempt_superblock_creation(dashd) # schedule the next run Scheduler.schedule_next_run()
def main(): dashd = DashDaemon.from_dash_conf(config.dash_conf) # check dashd connectivity if not is_dashd_port_open(dashd): print( "Cannot connect to dashd. Please ensure dashd is running and the JSONRPC port is open to Sentinel." ) sys.exit(2) # check dashd sync if not dashd.is_synced(): print( "dashd not synced with network! Awaiting full sync before running Sentinel." ) sys.exit(2) # ======================================================================== # general flow: # ======================================================================== # # load "gobject list" rpc command data & create new objects in local MySQL DB perform_dashd_object_sync(dashd) # delete old watchdog objects, create a new if necessary watchdog_check(dashd) # auto vote network objects as valid/invalid check_object_validity(dashd) # create a Superblock if necessary attempt_superblock_creation(dashd)
def test_deterministic_superblock_selection(go_list_superblocks): from dashd import DashDaemon dashd = DashDaemon.from_dash_conf(config.dash_conf) for item in go_list_superblocks: (go, subobj) = GovernanceObject.import_gobject_from_dashd(dashd, item) # highest hash wins if same -- so just order by hash sb = Superblock.find_highest_deterministic('542f4433e438bdd64697b8381fda1a7a9b7a111c3a4e32fad524d1821d820394') assert sb.object_hash == 'bc2834f357da7504138566727c838e6ada74d079e63b6104701f4f8eb05dae36'
def test_deterministic_superblock_selection(go_list_superblocks): from dashd import DashDaemon dashd = DashDaemon.from_dash_conf(config.dash_conf) for item in go_list_superblocks: (go, subobj) = GovernanceObject.import_gobject_from_dashd(dashd, item) # highest hash wins if same -- so just order by hash sb = Superblock.find_highest_deterministic('22a5f429c5ffb2b79b1b30c3ac30751284e3efa4e710bc7fd35fbe7456b1e485') assert sb.object_hash == 'bc2834f357da7504138566727c838e6ada74d079e63b6104701f4f8eb05dae36'
def test_approved_and_ranked(go_list_proposals): from dashd import DashDaemon dashd = DashDaemon.from_dash_conf(config.dash_conf) for item in go_list_proposals: (go, subobj) = GovernanceObject.import_gobject_from_dashd(dashd, item) prop_list = Proposal.approved_and_ranked(proposal_quorum=1, next_superblock_max_budget=60) assert prop_list[0].object_hash == u'dfd7d63979c0b62456b63d5fc5306dbec451180adee85876cbf5b28c69d1a86c' assert prop_list[1].object_hash == u'0523445762025b2e01a2cd34f1d10f4816cf26ee1796167e5b029901e5873630'
def test_deterministic_superblock_selection(go_list_superblocks): from dashd import DashDaemon dashd = DashDaemon.from_dash_conf(config.dash_conf) for item in go_list_superblocks: (go, subobj) = GovernanceObject.import_gobject_from_dashd(dashd, item) # highest hash wins if same -- so just order by hash sb = Superblock.find_highest_deterministic( '5c7c28ddec8c1ad54b49f6f1e79369e7ccaf76f5ddc30e502569d674e458ccf3') assert sb.object_hash == 'bc2834f357da7504138566727c838e6ada74d079e63b6104701f4f8eb05dae36'
def test_deterministic_superblock_creation(go_list_proposals): import dashlib from dashd import DashDaemon dashd = DashDaemon.from_dash_conf(config.dash_conf) for item in go_list_proposals: (go, subobj) = GovernanceObject.import_gobject_from_dashd(dashd, item) prop_list = Proposal.approved_and_ranked(dashd) sb = dashlib.create_superblock(dashd, prop_list, 72000) assert sb.event_block_height == 72000 assert sb.payment_addresses == 'yYe8KwyaUu5YswSYmB3q3ryx8XTUu9y7Ui|yYe8KwyaUu5YswSYmB3q3ryx8XTUu9y7Ui' assert sb.payment_amounts == '25.75000000|25.75000000' assert sb.hex_hash( ) == 'f740f95ef49b050f522ba2bda921819b72dbab7c622bfdd3786624e3fbf6e25f'
def test_deterministic_superblock_creation(go_list_proposals): import dashlib import misc from dashd import DashDaemon dashd = DashDaemon.from_dash_conf(config.dash_conf) for item in go_list_proposals: (go, subobj) = GovernanceObject.import_gobject_from_dashd(dashd, item) max_budget = 60 prop_list = Proposal.approved_and_ranked(proposal_quorum=1, next_superblock_max_budget=max_budget) sb = dashlib.create_superblock(prop_list, 72000, budget_max=max_budget, sb_epoch_time=misc.now()) assert sb.event_block_height == 72000 assert sb.payment_addresses == 'yYe8KwyaUu5YswSYmB3q3ryx8XTUu9y7Ui|yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV' assert sb.payment_amounts == '25.75000000|32.01000000' assert sb.proposal_hashes == 'dfd7d63979c0b62456b63d5fc5306dbec451180adee85876cbf5b28c69d1a86c|0523445762025b2e01a2cd34f1d10f4816cf26ee1796167e5b029901e5873630' assert sb.hex_hash() == '5534e9fa4a51423820b9e19fa6d4770c12ea0a5663e8adff8223f5e8b6df641c'
def test_superblock_is_valid(superblock): from dashd import DashDaemon dashd = DashDaemon.from_dash_conf(config.dash_conf) current_ebh = dashd.next_superblock_height() superblock.event_block_height = current_ebh orig = Superblock(**superblock.get_dict()) # make a copy # original as-is should be valid assert orig.is_valid(dashd) == True # mess with payment amounts superblock.payment_amounts = '7|yyzx' assert superblock.is_valid(dashd) == False superblock.payment_amounts = '7,|yzx' assert superblock.is_valid(dashd) == False # reset superblock.payment_amounts = orig.payment_amounts assert superblock.is_valid(dashd) == True # mess with payment addresses superblock.payment_addresses = 'yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV|1234 Anywhere ST, Chicago, USA' assert superblock.is_valid(dashd) == False # single payment addr/amt is ok superblock.payment_addresses = 'yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV' superblock.payment_amounts = '5.00' assert superblock.is_valid(dashd) == True # ensure number of payment addresses matches number of payments superblock.payment_addresses = 'yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV' superblock.payment_amounts = '37.00|23.24' assert superblock.is_valid(dashd) == False superblock.payment_addresses = 'yYe8KwyaUu5YswSYmB3q3ryx8XTUu9y7Ui|yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV' superblock.payment_amounts = '37.00' assert superblock.is_valid(dashd) == False # ensure amounts greater than zero superblock.payment_addresses = 'yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV' superblock.payment_amounts = '-37.00' assert superblock.is_valid(dashd) == False
def test_deterministic_superblock_creation(go_list_proposals): import dashlib import misc from dashd import DashDaemon dashd = DashDaemon.from_dash_conf(config.dash_conf) for item in go_list_proposals: (go, subobj) = GovernanceObject.import_gobject_from_dashd(dashd, item) max_budget = 60 prop_list = Proposal.approved_and_ranked(proposal_quorum=1, next_superblock_max_budget=max_budget) # MAX_GOVERNANCE_OBJECT_DATA_SIZE defined in governance-object.h maxgovobjdatasize = 16 * 1024 sb = dashlib.create_superblock(prop_list, 72000, max_budget, misc.now(), maxgovobjdatasize) assert sb.event_block_height == 72000 assert sb.payment_addresses == 'yYe8KwyaUu5YswSYmB3q3ryx8XTUu9y7Ui|yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV' assert sb.payment_amounts == '25.75000000|32.01000000' assert sb.proposal_hashes == 'dfd7d63979c0b62456b63d5fc5306dbec451180adee85876cbf5b28c69d1a86c|0523445762025b2e01a2cd34f1d10f4816cf26ee1796167e5b029901e5873630' assert sb.hex_hash() == 'bb3f33ccf95415c396bd09d35325dbcbc7b067010d51c7ccf772a9e839c1e414'
def test_superblock_size_limit(go_list_proposals): import dashlib import misc from dashd import DashDaemon dashd = DashDaemon.from_dash_conf(config.dash_conf) for item in go_list_proposals: (go, subobj) = GovernanceObject.import_gobject_from_dashd(dashd, item) max_budget = 60 prop_list = Proposal.approved_and_ranked(proposal_quorum=1, next_superblock_max_budget=max_budget) maxgovobjdatasize = 469 sb = dashlib.create_superblock(prop_list, 72000, max_budget, misc.now(), maxgovobjdatasize) # two proposals in the list, but... assert len(prop_list) == 2 # only one should have been included in the SB, because the 2nd one is over the limit assert sb.event_block_height == 72000 assert sb.payment_addresses == 'yYe8KwyaUu5YswSYmB3q3ryx8XTUu9y7Ui' assert sb.payment_amounts == '25.75000000' assert sb.proposal_hashes == 'dfd7d63979c0b62456b63d5fc5306dbec451180adee85876cbf5b28c69d1a86c' assert sb.hex_hash() == '6b8cababf797644f1d62003e4cc68c1c40a8c1873c8a68ed0fc88772ea77cc44'
def test_proposal_is_valid(proposal): from dashd import DashDaemon import dashlib dashd = DashDaemon.from_dash_conf(config.dash_conf) orig = Proposal(**proposal.get_dict()) # make a copy # fixture as-is should be valid assert proposal.is_valid() is True # ============================================================ # ensure end_date not greater than start_date # ============================================================ proposal.end_epoch = proposal.start_epoch assert proposal.is_valid() is False proposal.end_epoch = proposal.start_epoch - 1 assert proposal.is_valid() is False proposal.end_epoch = proposal.start_epoch + 0 assert proposal.is_valid() is False proposal.end_epoch = proposal.start_epoch + 1 assert proposal.is_valid() is True # reset proposal = Proposal(**orig.get_dict()) # ============================================================ # ensure valid proposal name # ============================================================ proposal.name = ' heya!@209h ' assert proposal.is_valid() is False proposal.name = "anything' OR 'x'='x" assert proposal.is_valid() is False proposal.name = ' ' assert proposal.is_valid() is False proposal.name = '' assert proposal.is_valid() is False proposal.name = '0' assert proposal.is_valid() is True proposal.name = 'R66-Y' assert proposal.is_valid() is True # binary gibberish proposal.name = dashlib.deserialise( '22385c7530303933375c75303363375c75303232395c75303138635c75303064335c75303163345c75303264385c75303236615c75303134625c75303163335c75303063335c75303362385c75303266615c75303261355c75303266652f2b5c75303065395c75303164655c75303136655c75303338645c75303062385c75303138635c75303064625c75303064315c75303038325c75303133325c753032333222' ) assert proposal.is_valid() is False # reset proposal = Proposal(**orig.get_dict()) # ============================================================ # ensure valid payment address # ============================================================ proposal.payment_address = '7' assert proposal.is_valid() is False proposal.payment_address = 'YYE8KWYAUU5YSWSYMB3Q3RYX8XTUU9Y7UI' assert proposal.is_valid() is False proposal.payment_address = 'yYe8KwyaUu5YswSYmB3q3ryx8XTUu9y7Uj' assert proposal.is_valid() is False proposal.payment_address = '221 B Baker St., London, United Kingdom' assert proposal.is_valid() is False # this is actually the Dash foundation multisig address... proposal.payment_address = '7gnwGHt17heGpG9Crfeh4KGpYNFugPhJdh' assert proposal.is_valid() is False proposal.payment_address = 'yYe8KwyaUu5YswSYmB3q3ryx8XTUu9y7Ui' assert proposal.is_valid() is True # reset proposal = Proposal(**orig.get_dict()) # validate URL proposal.url = ' ' assert proposal.is_valid() is False proposal.url = ' ' assert proposal.is_valid() is False proposal.url = 'http://bit.ly/1e1EYJv' assert proposal.is_valid() is True proposal.url = 'https://example.com/resource.ext?param=1&other=2' assert proposal.is_valid() is True proposal.url = 'www.com' assert proposal.is_valid() is True proposal.url = 'v.ht/' assert proposal.is_valid() is True proposal.url = 'ipfs:///ipfs/QmPwwoytFU3gZYk5tSppumxaGbHymMUgHsSvrBdQH69XRx/' assert proposal.is_valid() is True proposal.url = '/ipfs/QmPwwoytFU3gZYk5tSppumxaGbHymMUgHsSvrBdQH69XRx/' assert proposal.is_valid() is True proposal.url = 's3://bucket/thing/anotherthing/file.pdf' assert proposal.is_valid() is True proposal.url = 'http://zqktlwi4fecvo6ri.onion/wiki/index.php/Main_Page' assert proposal.is_valid() is True proposal.url = 'ftp://ftp.funet.fi/pub/standards/RFC/rfc959.txt' assert proposal.is_valid() is True # gibberish URL proposal.url = dashlib.deserialise( '22687474703a2f2f5c75303330385c75303065665c75303362345c75303362315c75303266645c75303331345c625c75303134655c75303031615c75303139655c75303133365c75303264315c75303238655c75303364395c75303230665c75303363355c75303030345c75303336665c75303238355c75303165375c75303063635c75303139305c75303262615c75303239316a5c75303130375c75303362365c7530306562645c75303133335c75303335665c7530326562715c75303038655c75303332645c75303362645c75303064665c75303135654f365c75303237335c75303363645c7530333539275c75303165345c75303339615c75303365385c75303334345c75303130615c75303265662e5c75303231625c75303164356a5c75303232345c75303163645c75303336365c75303064625c75303339665c75303230305c75303337615c75303138395c75303263325c75303038345c75303066615c75303031335c75303233655c75303135345c75303165395c75303139635c75303239375c75303039355c75303038345c75303362305c7530306233435c75303135345c75303063665c75303163345c75303261335c75303362655c75303136305c75303139365c75303263665c75303131305c7530313031475c75303162645c75303338645c75303363325c75303138625c75303235625c75303266325c75303264635c75303139335c75303066665c75303066645c75303133625c75303234305c75303137615c75303062355c75303031645c75303238655c75303166315c75303232315c75303161615c75303265325c75303335625c75303333665c75303239345c75303335315c75303038345c75303339395c75303262385c75303132375c75303330357a5c75303263625c75303066305c75303062355c75303164335c75303338385c75303364385c75303130625c75303266325c75303137305c75303335315c75303030305c75303136385c75303039646d5c75303331315c75303236615c75303330375c75303332635c75303361635c665c75303363335c75303264365c75303238645c75303136395c7530323438635c75303163385c75303261355c75303164615c75303165375c75303337355c75303332645c7530333165755c75303131665c75303338375c75303135325c75303065325c75303135326c5c75303164325c75303164615c75303136645c75303061665c75303333375c75303264375c75303339375c75303139395c75303134635c75303165385c75303234315c75303336635c75303130645c75303230635c75303161615c75303339355c75303133315c75303064615c75303165615c75303336645c75303064325c75303337365c75303363315c75303132645c75303266305c75303064364f255c75303263635c75303162645c75303062385c75303238365c75303136395c75303337335c75303232335c75303336655c75303037665c75303062616b5c75303132365c75303233305c75303330645c75303362385c75303164355c75303166615c75303338395c75303062635c75303135325c75303334365c75303139645c75303135615c75303031395c75303061385c75303133615c75303338635c75303339625c75303261655c75303065395c75303362635c75303166385c75303031665c75303230615c75303263355c75303134335c75303361635c75303334355c75303236645c75303139365c75303362665c75303135615c75303137305c75303165395c75303231395c75303332665c75303232645c75303030365c75303066305c75303134665c75303337375c75303234325d5c75303164325c75303337655c75303265665c75303331395c75303261355c75303265385c75303338395c75303235645c75303334315c75303338395c7530323230585c75303062645c75303166365c75303238645c75303231375c75303066665c75303130385c75303331305c75303330335c75303031395c75303039635c75303363315c75303039615c75303334355c75303331305c75303162335c75303263315c75303132395c75303234335c75303038627c5c75303361335c75303261635c75303165655c75303030305c75303237615c75303038385c75303066355c75303232375c75303236635c75303236355c7530336336205c75303038615c7530333561787c735c75303336305c75303362655c75303235385c75303334345c75303264365c75303262355c75303361315c75303135345c75303131625c75303061625c75303038615c75303332655c75303238325c75303031393d5c75303263335c75303332655c75303163645c75303139305c75303231305c75303131365c75303334305c75303234665c75303162635c75303333645c75303135305c75303132335c75303233645c75303133345c75303062327a5c75303331635c75303136312a5c753032316522' ) assert proposal.is_valid() is False # reset proposal = Proposal(**orig.get_dict()) # ============================================================ # ensure proposal can't request negative dash # ============================================================ proposal.payment_amount = -1 assert proposal.is_valid() is False
# -*- coding: utf-8 -*- import pdb from pprint import pprint import re import sys import os sys.path.append(os.path.normpath(os.path.join(os.path.dirname(__file__), '../lib'))) import config from models import Superblock, Proposal, GovernanceObject, Setting, Signal, Vote, Outcome, Watchdog from models import VoteSignals, VoteOutcomes from peewee import PeeweeException # , OperationalError, IntegrityError from dashd import DashDaemon import dashlib from decimal import Decimal dashd = DashDaemon.from_dash_conf(config.dash_conf) import misc # ============================================================================== # do stuff here pr = Proposal( name='proposal7', url='https://dashcentral.com/proposal7', payment_address='yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV', payment_amount=39.23, start_epoch=1483250400, end_epoch=1491022800, ) # sb = Superblock( # event_block_height = 62500, # payment_addresses = "yYe8KwyaUu5YswSYmB3q3ryx8XTUu9y7Ui|yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV",
def test_superblock_is_valid(superblock): from dashd import DashDaemon dashd = DashDaemon.from_dash_conf(config.dash_conf) orig = Superblock(**superblock.get_dict()) # make a copy # original as-is should be valid assert orig.is_valid() is True # mess with payment amounts superblock.payment_amounts = '7|yyzx' assert superblock.is_valid() is False superblock.payment_amounts = '7,|yzx' assert superblock.is_valid() is False superblock.payment_amounts = '7|8' assert superblock.is_valid() is True superblock.payment_amounts = ' 7|8' assert superblock.is_valid() is False superblock.payment_amounts = '7|8 ' assert superblock.is_valid() is False superblock.payment_amounts = ' 7|8 ' assert superblock.is_valid() is False # reset superblock = Superblock(**orig.get_dict()) assert superblock.is_valid() is True # mess with payment addresses superblock.payment_addresses = 'yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV|1234 Anywhere ST, Chicago, USA' assert superblock.is_valid() is False # leading spaces in payment addresses superblock.payment_addresses = ' yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV' superblock.payment_amounts = '5.00' assert superblock.is_valid() is False # trailing spaces in payment addresses superblock.payment_addresses = 'yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV ' superblock.payment_amounts = '5.00' assert superblock.is_valid() is False # leading & trailing spaces in payment addresses superblock.payment_addresses = ' yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV ' superblock.payment_amounts = '5.00' assert superblock.is_valid() is False # single payment addr/amt is ok superblock.payment_addresses = 'yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV' superblock.payment_amounts = '5.00' assert superblock.is_valid() is True # ensure number of payment addresses matches number of payments superblock.payment_addresses = 'yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV' superblock.payment_amounts = '37.00|23.24' assert superblock.is_valid() is False superblock.payment_addresses = 'yYe8KwyaUu5YswSYmB3q3ryx8XTUu9y7Ui|yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV' superblock.payment_amounts = '37.00' assert superblock.is_valid() is False # ensure amounts greater than zero superblock.payment_addresses = 'yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV' superblock.payment_amounts = '-37.00' assert superblock.is_valid() is False # reset superblock = Superblock(**orig.get_dict()) assert superblock.is_valid() is True # mess with proposal hashes superblock.proposal_hashes = '7|yyzx' assert superblock.is_valid() is False superblock.proposal_hashes = '7,|yyzx' assert superblock.is_valid() is False superblock.proposal_hashes = '0|1' assert superblock.is_valid() is False superblock.proposal_hashes = '0000000000000000000000000000000000000000000000000000000000000000|1111111111111111111111111111111111111111111111111111111111111111' assert superblock.is_valid() is True # reset superblock = Superblock(**orig.get_dict()) assert superblock.is_valid() is True
def test_proposal_is_valid(proposal): from dashd import DashDaemon dashd = DashDaemon.from_dash_conf(config.dash_conf) # fixture as-is should be valid assert proposal.is_valid(dashd) == True # ============================================================ # ensure end_date not greater than start_date # ============================================================ proposal.end_epoch = proposal.start_epoch assert proposal.is_valid(dashd) == False proposal.end_epoch = proposal.start_epoch - 1 assert proposal.is_valid(dashd) == False proposal.end_epoch = proposal.start_epoch + 0 assert proposal.is_valid(dashd) == False proposal.end_epoch = proposal.start_epoch + 1 assert proposal.is_valid(dashd) == True # reset proposal.end_epoch = 1491022800 # ============================================================ # ensure valid proposal name # ============================================================ name = proposal.name proposal.name = ' heya!@209h ' assert proposal.is_valid(dashd) == False proposal.name = "anything' OR 'x'='x" assert proposal.is_valid(dashd) == False proposal.name = ' ' assert proposal.is_valid(dashd) == False proposal.name = '' assert proposal.is_valid(dashd) == False proposal.name = '0' assert proposal.is_valid(dashd) == True proposal.name = 'R66-Y' assert proposal.is_valid(dashd) == True # reset proposal.name = name # ============================================================ # ensure proposal not too late # ============================================================ proposal.end_epoch = misc.now() - 1 assert proposal.is_valid(dashd) == False proposal.end_epoch = misc.now() assert proposal.is_valid(dashd) == False proposal.start_epoch = misc.now() + 2 proposal.end_epoch = misc.now() + 4 assert proposal.is_valid(dashd) == True # reset proposal.start_epoch = 1483250400 proposal.end_epoch = 1491022800 # ============================================================ # ensure valid payment address # ============================================================ proposal.payment_address = '7' assert proposal.is_valid(dashd) == False proposal.payment_address = 'YYE8KWYAUU5YSWSYMB3Q3RYX8XTUU9Y7UI' assert proposal.is_valid(dashd) == False proposal.payment_address = 'yYe8KwyaUu5YswSYmB3q3ryx8XTUu9y7Uj' assert proposal.is_valid(dashd) == False proposal.payment_address = '221 B Baker St., London, United Kingdom' assert proposal.is_valid(dashd) == False # this is actually the Dash foundation multisig address... proposal.payment_address = '7gnwGHt17heGpG9Crfeh4KGpYNFugPhJdh' assert proposal.is_valid(dashd) == False proposal.payment_address = 'yYe8KwyaUu5YswSYmB3q3ryx8XTUu9y7Ui' assert proposal.is_valid(dashd) == True # validate URL (ish) proposal.url = 'www.com' assert proposal.is_valid(dashd) == True proposal.url = ' ' assert proposal.is_valid(dashd) == False proposal.url = ' ' assert proposal.is_valid(dashd) == False proposal.url = 'v.ht/' assert proposal.is_valid(dashd) == True # ============================================================ # ensure proposal can't request more than the budget # ============================================================ max_budget = 7000 # it's over 9000! proposal.payment_amount = 9001 assert proposal.is_valid(dashd) == False proposal.payment_amount = -1 assert proposal.is_valid(dashd) == False
# -*- coding: utf-8 -*- import pdb from pprint import pprint import re import sys import os sys.path.append(os.path.normpath(os.path.join(os.path.dirname(__file__), '../lib'))) import config from models import Superblock, Proposal, GovernanceObject, Setting, Signal, Vote, Outcome from models import VoteSignals, VoteOutcomes from peewee import PeeweeException # , OperationalError, IntegrityError from dashd import DashDaemon import dashlib from decimal import Decimal print("CONFIG: ", config.scope_conf) dashd = DashDaemon.from_dash_conf(config.scope_conf) import misc # ============================================================================== # do stuff here pr = Proposal( name='proposal7', url='https://dashcentral.com/proposal7', payment_address='yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV', payment_amount=39.23, start_epoch=1483250400, end_epoch=1491022800, ) # sb = Superblock( # event_block_height = 62500,