def list(): if request.method == 'GET': return render_template('proposals/list.html', proposals=get_sanitized_proposals()) else: # POST proposal = Proposal(created_by=request.form['created_by'], number=request.form['number']) proposal.save() return render_template('proposals/list.html', proposals=get_sanitized_proposals())
def proposals(request): was_limited = getattr(request, 'limited', False) if was_limited: return JsonResponse( { 'status': 'you hit the rate limit!' } ) else: token = get_token(request) user_id_login = User.verify_auth_token(token) if user_id_login: if request.method == 'GET': all_request = Request.objects.filter(user_id=user_id_login) request_id = [] for r in all_request: request_id.append(r.id) all_proposal = Proposal.objects.filter(request_id in request_id) data = [] for proposal in all_proposal: item = { 'id': proposal.id, 'user_proposed_to': proposal.user_proposed_to, 'user-proposed_from': proposal.user_proposed_from, 'request_id': proposal.request_id.id, 'filled': proposal.filled } data.append(item) return JsonResponse( { 'objects': data } ) elif request.method == 'POST': request_id = request.POST.get('request_id') user_from = Request.objects.filter(id=request_id).first().user_id user_to = user_id_login if user_from == user_to: return HttpResponseForbidden('the two users are same') else: proposal = Proposal(user_proposed_to=user_to, user_proposed_from=user_from, request_id=request_id) proposal.save() return JsonResponse( { 'status': 'proposal created successfully', 'object': { 'id': proposal.id, 'user_proposed_to': proposal.user_proposed_to, 'user-proposed_from': proposal.user_proposed_from, 'request_id': proposal.request_id.id, 'filled': proposal.filled } } ) else: return HttpResponseForbidden('invalid token')
def get(self, request, *args, **kwargs): serializer = Proposal(Pitch.objects.get(pk=kwargs['pk'])) if self.request.accepted_renderer.format == 'html': # we have to set unpack the tree structure here for the template serializer.data['comments'] = RenderTree( serializer.data['comments']) return Response({'proposal': serializer.data}, template_name='proposal_detail.html') return Response(serializer.data)
def get(self, confid, secret): """Download all speakers and proposals for a conference""" # Super-Reviewers committee = [] if confid == 'droidcon-2016': committee = ['*****@*****.**', '*****@*****.**'] # get conference conference = Conference.get_by_id(confid) # check if the provided secret is correct if conference.secret != secret: self.response.http_status_message(403) return speakers = Speaker.query() proposals = Proposal.query(ancestor=conference.key) reviews = Review.query() speakers_dict = [dict(s.to_dict(), **dict(id=s.key.id())) for s in speakers] proposals_dict = [] # create a fast lookup table - reviews by parent reviews_by_parent = {} for r in reviews: parent = r.key.parent() rlist = reviews_by_parent[parent] if rlist is None: rlist = [] rlist.append(r) reviews_by_parent[parent] = rlist # crete a fast lookup table - speaker by key speakers_by_id = {} for s in speakers: speakers_by_key[s.key] = s for p in proposals: p_dict = p.to_dict() p_dict['id'] = p.key.id() p_r = {} p_sum = 0 for r in reviews_by_parent[p.key]: p_r[r.key.id()] = r.to_dict() if r.rating: if r.key.id() in committee: # double the rating! p_sum = p_sum + r.rating p_sum = p_sum + r.rating s = speakers_by_key[p.speaker] if s is not None: p_dict['speaker-email'] = s.email p_dict['speaker-name'] = s.name p_dict['speaker-surname'] = s.surname if s.rating: p_sum = p_sum + s.rating p_dict['reviews'] = p_r p_dict['rating'] = p_sum proposals_dict.append(p_dict) self.response.headers['Content-Type'] = 'application/json' obj = { 'speakers': speakers_dict, 'proposals': proposals_dict, } self.response.out.write(json.dumps(obj, cls=DatastoreEncoder))
def ajaxproposalvote(request, proposal_slug, score): # get vars proposal = get_object_or_404(Proposal.objects, slug=proposal_slug) user = request.user ajax_response = lambda msgtype, message: HttpResponse("{}\n{}".format(msgtype, message), mimetype='text/plain') # check legality of vote assert score in dict(Proposal.voteOptions()).keys(), 'illegal vote' votevalue = int(float(score)) # check if vote is in progress if proposal.voting_stage != 'VOTING': return ajax_response(msgtype='error', message="Error: vote is no longer in progress") # check if user is cancelling vote if proposal.userHasProposalvoted(user) == votevalue: ## cancel vote vote = proposal.proposalvoteFromUser(user) vote.delete() return ajax_response(msgtype='success', message="Your vote was removed") else: ## remove existing and cast new vote # remove the previous vote of the user if proposal.userHasProposalvoted(user) != None: vote = proposal.proposalvoteFromUser(user) vote.delete() # create ProposalVote vote = ProposalVote( user = user, proposal = proposal, value = votevalue, ) vote.save() return ajax_response(msgtype='success', message="Your vote was cast successfully")
def post(self, confid): user = users.get_current_user() if not user: login_url = users.create_login_url(self.request.url) self.redirect(login_url) return # get the conference if confid.startswith('new:'): confid = confid[4:] conference = Conference.get_by_id(confid) # check if the user is an admin if user.email() not in conference.reviewers: self.response.out.write("You are not authorized") return # get proposal id & proposal proposal_id = long(self.request.get('proposal_id')) proposal = Proposal.get_by_id(id=proposal_id, parent=conference.key) if not proposal: self.response.out.write("No proposal found for this id (" + str(proposal_id) + ")") return # get existing review by this user review = Review.get_by_id(id=user.email(), parent=proposal.key) if not review: review = Review(id=user.email(), parent=proposal.key) # store value for the review review.comment = self.request.get('comment') if self.request.get('rating'): review.rating = int(self.request.get('rating')) # store in Data Store review.put() # redirect to get self.redirect(self.request.url)
def update_proposal(id): user = g.user if not request.json: abort(400) errors = Proposal.validate(request.json) if len(errors) == 0: return jsonify( { 'result': True } ) return jsonify({"message": "The request is invalid."},errors = [error for error in errors]) ,400
def get_sanitized_proposals(): proposals = Proposal.objects(archived=False) for proposal in proposals: if not proposal.votes_revealed: for vote in proposal.votes: vote.vote = "[hidden]" vote.hate_upon = "[hidden]" vote.love = "[hidden]" return proposals
def post(self, confid): """Accept proposals via POST requests""" # get parameters from request name = self.request.get("name") surname = self.request.get("surname") email = self.request.get("email") bio = self.request.get("bio") useOld = self.request.get("use-old") title = self.request.get("title") abstract = self.request.get("abstract") duration = int(self.request.get("duration")) comment = self.request.get("comment") # timestamp 'now' now = datetime.now() # search for conference conference = Conference.get_by_id(confid) if not conference: self.error("Conference not found", 404) return # search for speaker? speakerKey = None if useOld: # get speakers for email speakers = Speaker.query(Speaker.email == email) # and order by modified-date (reverse) to get the last one speakers = speakers.order(-Speaker.modified).iter() if speakers.has_next(): speaker = speakers.next() speakerKey = speaker.key if not speakerKey: # create speaker object speaker = Speaker(name=name, surname=surname, email=email, bio=bio, created=now, modified=now) speakerKey = speaker.put() # submit proposal proposal = Proposal(parent=conference.key, speaker=speakerKey, abstract=abstract, duration=duration, title=title, comment=comment, created=now, modified=now) proposalKey = proposal.put() if proposalKey: self.success() else: self.error("Error when storing proposal", 500)
def submitProposal(self, request): """Submit a new talk proposal""" if not request.title or not request.speaker: raise endpoints.BadRequestException( "Required field (title and/or speaker key) missing" ) # get the speaker (check if it exists) speaker = ndb.Key(urlsafe=request.speaker).get() if not speaker: raise endpoints.BadRequestException( "Speaker entity not found" ) if speaker.key.kind() != "Speaker": raise endpoints.BadRequestException( "Invalid key kind for speaker specified" ) # get the conference (check if it exists) conf = Conference.get_by_id(request.conferenceId) if not conf: raise endpoints.BadRequestException( "Invalid conference identifier specified" ) # TODO: check if call for papers is still open # fill the data structure for creating the entity data = {field.name: getattr(request, field.name) for field in request.all_fields()} # delete conference id, link to parent del data['conferenceId'] data['parent'] = conf.key # update the speaker reference data['speaker'] = speaker.key # set the created date/time stamp data['created'] = datetime.now() data['modified'] = data['created'] # store in Datastore - with correct parent proposalKey = Proposal(**data).put() # return value retVal = ProposalKeyForm() retVal.key = proposalKey.urlsafe() retVal.title = request.title return retVal
def new_proposal(): user = g.user if not request.json: abort(400) errors = Proposal.validate(request.json) if len(errors) == 0: request_id = request.json.get('request_id') r = session.query(Request).filter_by(id = request_id).first() if r is None: return jsonify({"message": "The request is invalid."},errors = [dict({"request_id":"Request does not exist"})]) ,400 if user.id == r.user_id: abort(403) proposal = Proposal(user_proposed_from = user.id, user_proposed_to = r.user_id, request_id = r.id ) session.add(proposal) session.commit() return jsonify( { 'result': True } ) return jsonify({"message": "The request is invalid."},errors = [error for error in errors]) ,400
def get(self, confid): user = users.get_current_user() if not user: login_url = users.create_login_url(self.request.url) self.redirect(login_url) return new_only = confid.startswith('new:') if new_only: confid = confid[4:] # get the conference conference = Conference.get_by_id(confid) # check if the user is an admin if user.email() not in conference.reviewers: self.response.out.write("You are not authorized") return # get existing proposals proposals = Proposal.query(ancestor=conference.key).fetch() # get existing reviews reviews = Review.query(ancestor=conference.key).fetch() # filter by this users reviews = [r for r in reviews if r.key.id() == user.email()] proposals_reviewed = [] # add the review to the matching proposal for r in reviews: for p in proposals: if r.key.parent() == p.key: p.review = r proposals_reviewed.append(p.key) if new_only: proposals = [p for p in proposals if p.key not in proposals_reviewed] # set of stuff to display in the template template_values = { 'user': user, 'logout_url': users.create_logout_url(self.request.url), 'conference': conference, 'proposals': proposals, 'reviews': reviews, } # display template with the reviews & proposals template = JINJA_ENVIRONMENT.get_template('review.html') self.response.write(template.render(template_values))
superblockcycle = node1.superblockcycle() nextsuperblock = node1.next_superblock_height() curblock = node1.last_superblock_height() if nextsuperblock - curblock > 10: start_epoch = curunixtime else: start_epoch = int(curunixtime + (superblockcycle * 2.6 * 60)) end_epoch = int(start_epoch + payout_month * (superblockcycle * 2.6 * 60) + ((superblockcycle / 2) * 2.6 * 60)) proposal = Proposal(name='proposal_' + str(curblock), url='https://dashcentral.com/proposal_' + str(curblock) + '_' + str(curunixtime), payment_address=payout_address, payment_amount=payout_amount, start_epoch=start_epoch, end_epoch=end_epoch, govobj_type=0) print proposal.govobj_type proposal.govobj_type = 0 #cmd = ['gobject', 'submit', '0', '1', str(curunixtime), proposal.dashd_serialise(), '0463c5b7194605e598441422a3dc99c7c96df4c943dd047310646ae2d8c43add'] cmd = [ 'gobject', 'submit', '0', '1', str(curunixtime), proposal.dashd_serialise(), '0000000000000000000000000000000000000000000000000000000000000000' ]
import config from models import Superblock, Proposal, GovernanceObject, Setting, Signal, Vote, Outcome from models import VoteSignals, VoteOutcomes from peewee import PeeweeException # , OperationalError, IntegrityError from zerooned import ZeroOneDaemon import zeroonelib from decimal import Decimal zerooned = ZeroOneDaemon.from_zeroone_conf(config.zeroone_conf) import misc # ============================================================================== # do stuff here pr = Proposal( name='proposal7', url='https://zeroonecentral.com/proposal7', payment_address='nF3PndkR4vttZKUpYdYQjDCCrfsfhNGs6A', payment_amount=39.23, start_epoch=1483250400, end_epoch=1491022800, ) # sb = Superblock( # event_block_height = 62500, # payment_addresses = "yYe8KwyaUu5YswSYmB3q3ryx8XTUu9y7Ui|yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV", # payment_amounts = "5|3" # ) # TODO: make this a test, mock 'zerooned' and tie a test block height to a # timestamp, ensure only unit testing a within_window method # # also, create the `within_window` or similar method & use that. #
def prune_expired_proposals(allgamescoind): # vote delete for old proposals for proposal in Proposal.expired(allgamescoind.superblockcycle()): proposal.vote(allgamescoind, VoteSignals.delete, VoteOutcomes.yes)
def NewProposalEndpoint(session, wallet): proposals = Proposal.select().join(ProposalDecision).where( Proposal.wallet == wallet.id, ProposalDecision.source != wallet.source) return jsonify([proposal.serialize() for proposal in proposals])
def prune_expired_proposals(sparksd): # vote delete for old proposals for proposal in Proposal.expired(sparksd.superblockcycle()): proposal.vote(sparksd, VoteSignals.delete, VoteOutcomes.yes)
def setup(): # clear tables first Vote.delete().execute() Proposal.delete().execute() GovernanceObject.delete().execute()
def post_submit(user=None, community=None): entry = Proposal(community='', title='', content='') if community is None: community = request.form.get('community') or None if community and community[0:2] == "c/": community = community[2:] if request.method == 'POST': try: entry.title = request.form.get('title') or '' entry.content = request.form.get('content') or '' entry.published = request.form.get('published') or True entry.vote_options = request.form.get('internalvote') or None entry.usepositions = (True if request.form.get('use-positions') == '' else False) entry.author = User.get(User.id == current_user.id) entry.community = Community.get(Community.name == community) if not (entry.title and entry.community and entry.author): flash('Community and Title are required.', 'error') else: entry.update_search_index() # Wrap the call to save in a transaction so we can roll it back # cleanly in the event of an integrity error. try: with database.atomic(): entry.save() except peewee.IntegrityError: flash('This title is already in use.', 'error') else: if entry.published: return redirect( url_for('post_details', community=entry.community.name, slug=entry.slug)) else: abort(404) except peewee.DoesNotExist: flash('Community and Title are required.', 'error') if community is not None: community = Community.get_or_none(Community.name == community) return render_template('submit.html', entry=entry, community=community)
def post_details(community, slug): query = Proposal.public() community_id = Community.get_or_none(Community.name == community) entry = get_object_or_404(query, Proposal.slug == slug, Proposal.community == community_id) return render_template('post.html', entry=entry, community=community_id)
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 quantisnetd = QuantisnetDaemon.from_quantisnet_conf(config.quantisnet_conf) import misc # ============================================================================== # do stuff here pr = Proposal( name='proposal7', url='https://quantisnetwork.org/proposal7', payment_address='QTC62huR4YQEPn9AJHjnQxxreHSbgAoatV', payment_amount=39.23, start_epoch=1483250400, end_epoch=1491022800, ) # sb = Superblock( # event_block_height = 62500, # payment_addresses = "yYe8KwyaUu5YswSYmB3q3ryx8XTUu9y7Ui|yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV", # payment_amounts = "5|3" # ) # TODO: make this a test, mock 'dashd' and tie a test block height to a # timestamp, ensure only unit testing a within_window method # # also, create the `within_window` or similar method & use that. #
def prune_expired_proposals(quantisnetd): # vote delete for old proposals for proposal in Proposal.expired(quantisnetd.superblockcycle()): proposal.vote(quantisnetd, VoteSignals.delete, VoteOutcomes.yes)
def prune_expired_proposals(genesisd): # vote delete for old proposals for proposal in Proposal.expired(genesisd.governanceblockcycle()): proposal.vote(genesisd, VoteSignals.delete, VoteOutcomes.yes)
if Superblock.is_voted_funding(event_block_height): # printdbg("ALREADY VOTED! 'til next time!") # vote down any new SBs because we've already chosen a winner for sb in Superblock.at_height(event_block_height): icbet sb.voted_on(signal=VoteSignals.funding): sb.vote(comboded, VoteSignals.funding, VoteOutcomes.no) # now return, we're done return icbet comboded.is_govobj_maturity_phase(): printdbg("Not in maturity phase yet -- will not attempt Superblock") return proposals = Proposal.approved_and_ranked(proposal_quorum=comboded.governance_quorum(), next_superblock_max_budget=comboded.next_superblock_max_budget()) budget_max = comboded.get_superblock_budget_allocation(event_block_height) sb_epoch_time = comboded.block_height_to_epoch(event_block_height) maxgovobjdatasize = comboded.govinfo['maxgovobjdatasize'] sb = combodelib.create_superblock(proposals, event_block_height, budget_max, sb_epoch_time, maxgovobjdatasize) icbet sb: printdbg("No superblock created, sorry. Returning.") return # find the deterministic SB w/highest object_hash in the DB dbrec = Superblock.find_highest_deterministic(sb.hex_hash()) if dbrec: dbrec.vote(comboded, VoteSignals.funding, VoteOutcomes.yes) # any other blocks which match the sb_hash are duplicates, delete them
def test_proposal_is_valid(proposal): from bitgreend import BitgreenDaemon import bitgreenlib bitgreend = BitgreenDaemon.from_bitgreen_conf(config.bitgreen_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 proposal.name = 'valid-name' assert proposal.is_valid() is True proposal.name = ' mostly-valid-name' assert proposal.is_valid() is False proposal.name = 'also-mostly-valid-name ' assert proposal.is_valid() is False proposal.name = ' similarly-kinda-valid-name ' assert proposal.is_valid() is False proposal.name = 'dean miller 5493' assert proposal.is_valid() is False proposal.name = 'dean-millerà-5493' assert proposal.is_valid() is False proposal.name = 'dean-миллер-5493' assert proposal.is_valid() is False # binary gibberish proposal.name = bitgreenlib.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 = 'GX8OZ5XBZABWU3VSJOP1QGPTO69MQTUK2K' 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 = 'gX8oZ5xbzAbwu3VSjoP1qgPTo69mqTuk2k' assert proposal.is_valid() is True proposal.payment_address = ' gX8oZ5xbzAbwu3VSjoP1qgPTo69mqTuk2k' assert proposal.is_valid() is False proposal.payment_address = 'gX8oZ5xbzAbwu3VSjoP1qgPTo69mqTuk2k ' assert proposal.is_valid() is False proposal.payment_address = ' gX8oZ5xbzAbwu3VSjoP1qgPTo69mqTuk2k ' assert proposal.is_valid() is False # 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 = ' http://bit.ly/1e1EYJv' assert proposal.is_valid() is False proposal.url = 'http://bit.ly/1e1EYJv ' assert proposal.is_valid() is False proposal.url = ' http://bit.ly/1e1EYJv ' assert proposal.is_valid() is False proposal.url = 'http://::12.34.56.78]/' assert proposal.is_valid() is False proposal.url = 'http://[::1/foo/bad]/bad' assert proposal.is_valid() is False proposal.url = 'http://dashcentral.org/dean-miller 5493' assert proposal.is_valid() is False proposal.url = 'http://dashcentralisé.org/dean-miller-5493' assert proposal.is_valid() is True proposal.url = 'http://dashcentralisé.org/dean-миллер-5493' 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 = bitgreenlib.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
superblockcycle = node1.superblockcycle() nextsuperblock = node1.next_superblock_height() curblock = node1.last_superblock_height() if nextsuperblock - curblock > 10: start_epoch = curunixtime else: start_epoch = int(curunixtime + (superblockcycle * 2.6 * 60)) end_epoch = int(start_epoch + payout_month * (superblockcycle * 2.6 * 60) + ((superblockcycle / 2) * 2.6 * 60)) proposal = Proposal(name='proposal_' + str(curblock), url='https://dashcentral.com/proposal_' + str(curblock) + '_' + str(curunixtime), payment_address=payout_address, payment_amount=payout_amount, start_epoch=start_epoch, end_epoch=end_epoch) print '\ntry to submit proposal with 0 confirmations' # should be permanently rejected by all nodes tx_hash0 = node1.rpc_command(*proposal.get_prepare_command()) print 'collateral tx hash: {0}\n'.format(tx_hash0) log1.expect_minimum('push_inventory:tx {0}'.format(tx_hash0), 1) cmd = [ 'gobject', 'submit', '0', '1', str(curunixtime), proposal.dashd_serialise(), tx_hash0 ]
import config from models import Superblock, Proposal, GovernanceObject, Setting, Signal, Vote, Outcome from models import VoteSignals, VoteOutcomes from peewee import PeeweeException # , OperationalError, IntegrityError from comboded import CombodeDaemon import combodelib from decimal import Decimal comboded = CombodeDaemon.from_combode_conf(config.combode_conf) import misc # ============================================================================== # do stuff here pr = Proposal( name='proposal7', url='https://combodecentral.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", # payment_amounts = "5|3" # ) # TODO: make this a test, mock 'comboded' and tie a test block height to a # timestamp, ensure only unit testing a within_window method # # also, create the `within_window` or similar method & use that. #
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 dynamicd import DynamicDaemon import dynamiclib from decimal import Decimal dynamicd = DynamicDaemon.from_dynamic_conf(config.dynamic_conf) import misc # ============================================================================== # do stuff here pr = Proposal( name='proposal7', url='https://duality.solutions/proposal7', payment_address='yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV', payment_amount=39.23, start_epoch=1483250400, end_epoch=1491022800, ) # sb = Superblock( # event_block_height = 62500, # payment_addresses = "yYe8KwyaUu5YswSYmB3q3ryx8XTUu9y7Ui|yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV", # payment_amounts = "5|3" # ) # TODO: make this a test, mock 'dynamicd' and tie a test block height to a # timestamp, ensure only unit testing a within_window method # # also, create the `within_window` or similar method & use that. #
def test_proposal_is_valid(proposal): from emixild import EmixilDaemon import emixillib emixild = EmixilDaemon.from_emixil_conf(config.emixil_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 = emixillib.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 Emixil 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 = emixillib.deserialise( '22687474703a2f2f5c75303330385c75303065665c75303362345c75303362315c75303266645c75303331345c625c75303134655c75303031615c75303139655c75303133365c75303264315c75303238655c75303364395c75303230665c75303363355c75303030345c75303336665c75303238355c75303165375c75303063635c75303139305c75303262615c75303239316a5c75303130375c75303362365c7530306562645c75303133335c75303335665c7530326562715c75303038655c75303332645c75303362645c75303064665c75303135654f365c75303237335c75303363645c7530333539275c75303165345c75303339615c75303365385c75303334345c75303130615c75303265662e5c75303231625c75303164356a5c75303232345c75303163645c75303336365c75303064625c75303339665c75303230305c75303337615c75303138395c75303263325c75303038345c75303066615c75303031335c75303233655c75303135345c75303165395c75303139635c75303239375c75303039355c75303038345c75303362305c7530306233435c75303135345c75303063665c75303163345c75303261335c75303362655c75303136305c75303139365c75303263665c75303131305c7530313031475c75303162645c75303338645c75303363325c75303138625c75303235625c75303266325c75303264635c75303139335c75303066665c75303066645c75303133625c75303234305c75303137615c75303062355c75303031645c75303238655c75303166315c75303232315c75303161615c75303265325c75303335625c75303333665c75303239345c75303335315c75303038345c75303339395c75303262385c75303132375c75303330357a5c75303263625c75303066305c75303062355c75303164335c75303338385c75303364385c75303130625c75303266325c75303137305c75303335315c75303030305c75303136385c75303039646d5c75303331315c75303236615c75303330375c75303332635c75303361635c665c75303363335c75303264365c75303238645c75303136395c7530323438635c75303163385c75303261355c75303164615c75303165375c75303337355c75303332645c7530333165755c75303131665c75303338375c75303135325c75303065325c75303135326c5c75303164325c75303164615c75303136645c75303061665c75303333375c75303264375c75303339375c75303139395c75303134635c75303165385c75303234315c75303336635c75303130645c75303230635c75303161615c75303339355c75303133315c75303064615c75303165615c75303336645c75303064325c75303337365c75303363315c75303132645c75303266305c75303064364f255c75303263635c75303162645c75303062385c75303238365c75303136395c75303337335c75303232335c75303336655c75303037665c75303062616b5c75303132365c75303233305c75303330645c75303362385c75303164355c75303166615c75303338395c75303062635c75303135325c75303334365c75303139645c75303135615c75303031395c75303061385c75303133615c75303338635c75303339625c75303261655c75303065395c75303362635c75303166385c75303031665c75303230615c75303263355c75303134335c75303361635c75303334355c75303236645c75303139365c75303362665c75303135615c75303137305c75303165395c75303231395c75303332665c75303232645c75303030365c75303066305c75303134665c75303337375c75303234325d5c75303164325c75303337655c75303265665c75303331395c75303261355c75303265385c75303338395c75303235645c75303334315c75303338395c7530323230585c75303062645c75303166365c75303238645c75303231375c75303066665c75303130385c75303331305c75303330335c75303031395c75303039635c75303363315c75303039615c75303334355c75303331305c75303162335c75303263315c75303132395c75303234335c75303038627c5c75303361335c75303261635c75303165655c75303030305c75303237615c75303038385c75303066355c75303232375c75303236635c75303236355c7530336336205c75303038615c7530333561787c735c75303336305c75303362655c75303235385c75303334345c75303264365c75303262355c75303361315c75303135345c75303131625c75303061625c75303038615c75303332655c75303238325c75303031393d5c75303263335c75303332655c75303163645c75303139305c75303231305c75303131365c75303334305c75303234665c75303162635c75303333645c75303135305c75303132335c75303233645c75303133345c75303062327a5c75303331635c75303136312a5c753032316522' ) assert proposal.is_valid() is False # reset proposal = Proposal(**orig.get_dict()) # ============================================================ # ensure proposal can't request negative emixil # ============================================================ proposal.payment_amount = -1 assert proposal.is_valid() is False
def prune_expired_proposals(monsternoded): # vote delete for old proposals for proposal in Proposal.expired(monsternoded.superblockcycle()): proposal.vote(monsternoded, VoteSignals.delete, VoteOutcomes.yes)
def attempt_superblock_creation(sparksd): import sparkslib if not sparksd.is_masternode(): print("We are not a Masternode... can't submit superblocks!") return # query votes for this specific ebh... if we have voted for this specific # ebh, then it's voted on. since we track votes this is all done using joins # against the votes table # # has this masternode voted on *any* superblocks at the given event_block_height? # have we voted FUNDING=YES for a superblock for this specific event_block_height? event_block_height = sparksd.next_superblock_height() if Superblock.is_voted_funding(event_block_height): # printdbg("ALREADY VOTED! 'til next time!") # vote down any new SBs because we've already chosen a winner for sb in Superblock.at_height(event_block_height): if not sb.voted_on(signal=VoteSignals.funding): sb.vote(sparksd, VoteSignals.funding, VoteOutcomes.no) # now return, we're done return if not sparksd.is_govobj_maturity_phase(): printdbg("Not in maturity phase yet -- will not attempt Superblock") return proposals = Proposal.approved_and_ranked( proposal_quorum=sparksd.governance_quorum(), next_superblock_max_budget=sparksd.next_superblock_max_budget()) budget_max = sparksd.get_superblock_budget_allocation(event_block_height) sb_epoch_time = sparksd.block_height_to_epoch(event_block_height) maxgovobjdatasize = sparksd.govinfo['maxgovobjdatasize'] sb = sparkslib.create_superblock(proposals, event_block_height, budget_max, sb_epoch_time, maxgovobjdatasize) if not sb: printdbg("No superblock created, sorry. Returning.") return # find the deterministic SB w/highest object_hash in the DB dbrec = Superblock.find_highest_deterministic(sb.hex_hash()) if dbrec: dbrec.vote(sparksd, VoteSignals.funding, VoteOutcomes.yes) # any other blocks which match the sb_hash are duplicates, delete them for sb in Superblock.select().where( Superblock.sb_hash == sb.hex_hash()): if not sb.voted_on(signal=VoteSignals.funding): sb.vote(sparksd, VoteSignals.delete, VoteOutcomes.yes) printdbg( "VOTED FUNDING FOR SB! We're done here 'til next superblock cycle." ) return else: printdbg("The correct superblock wasn't found on the network...") # if we are the elected masternode... if (sparksd.we_are_the_winner()): printdbg("we are the winner! Submit SB to network") sb.submit(sparksd)
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 galactrumd import GalactrumDaemon import galactrumlib from decimal import Decimal galactrumd = GalactrumDaemon.from_galactrum_conf(config.galactrum_conf) import misc # ============================================================================== # do stuff here pr = Proposal( name='proposal7', url='https://voting.galactrum.org/proposal7', payment_address='yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV', payment_amount=39.23, start_epoch=1483250400, end_epoch=1491022800, ) # sb = Superblock( # event_block_height = 62500, # payment_addresses = "yYe8KwyaUu5YswSYmB3q3ryx8XTUu9y7Ui|yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV", # payment_amounts = "5|3" # ) # TODO: make this a test, mock 'galactrumd' and tie a test block height to a # timestamp, ensure only unit testing a within_window method # # also, create the `within_window` or similar method & use that.
def setup(): # clear tables first... Vote.delete().execute() Proposal.delete().execute() Superblock.delete().execute() GovernanceObject.delete().execute()
import config from models import Superblock, Proposal, GovernanceObject, Setting, Signal, Vote, Outcome from models import VoteSignals, VoteOutcomes from peewee import PeeweeException # , OperationalError, IntegrityError from polisd import PolisDaemon import polislib from decimal import Decimal polisd = PolisDaemon.from_polis_conf(config.polis_conf) import misc # ============================================================================== # do stuff here pr = Proposal( name='proposal7', url='https://poliscentral.com/proposal7', payment_address='TDWz9KfMo55wzj2brbgaXxnDz28nAbdPcY', payment_amount=39.23, start_epoch=1483250400, end_epoch=1491022800, ) # sb = Superblock( # event_block_height = 62500, # payment_addresses = "TXDSaTXerg68SCyLkWw2ERsqoTMWRBZiZQ|TDWz9KfMo55wzj2brbgaXxnDz28nAbdPcY", # payment_amounts = "5|3" # ) # TODO: make this a test, mock 'polisd' and tie a test block height to a # timestamp, ensure only unit testing a within_window method # # also, create the `within_window` or similar method & use that. #
def prune_expired_proposals(crowdclassicd): # vote delete for old proposals for proposal in Proposal.expired(crowdclassicd.superblockcycle()): proposal.vote(crowdclassicd, VoteSignals.delete, VoteOutcomes.yes)
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 lucentd import lucentDaemon import lucentlib from decimal import Decimal lucentd = lucentDaemon.from_lucent_conf(config.lucent_conf) import misc # ============================================================================== # do stuff here pr = Proposal( name='proposal7', url='https://gobytecentral.com/proposal7', payment_address='nJUUwdV8JvDXjoMLhmqi9mQCgiA86xPL4h', payment_amount=39.23, start_epoch=1483250400, end_epoch=1491022800, ) # sb = Superblock( # event_block_height = 62500, # payment_addresses = "n7mzEvBy6JdP2QQUqJrLjitucQKgTBZAR2|nJUUwdV8JvDXjoMLhmqi9mQCgiA86xPL4h", # payment_amounts = "5|3" # ) # TODO: make this a test, mock 'gobyted' and tie a test block height to a # timestamp, ensure only unit testing a within_window method # # also, create the `within_window` or similar method & use that. #
import config from models import Superblock, Proposal, GovernanceObject, Setting, Signal, Vote, Outcome from models import VoteSignals, VoteOutcomes from peewee import PeeweeException # , OperationalError, IntegrityError from trivechaind import TrivechainDaemon import trivechainlib from decimal import Decimal trivechaind = TrivechainDaemon.from_trivechain_conf(config.trivechain_conf) import misc # ============================================================================== # do stuff here pr = Proposal( name='proposal7', url='https://gov.trivechain.com/proposal7', payment_address='t7RKTBNZsTbjwAoXYfsSsTSwimxzDKh5Fu', payment_amount=39.23, start_epoch=1483250400, end_epoch=1491022800, ) # sb = Superblock( # event_block_height = 62500, # payment_addresses = "tCa7rDMXs1KeqaqmcFoXxXMmwT9eq9r7oK|t7RKTBNZsTbjwAoXYfsSsTSwimxzDKh5Fu", # payment_amounts = "5|3" # ) # TODO: make this a test, mock 'trivechaind' and tie a test block height to a # timestamp, ensure only unit testing a within_window method # # also, create the `within_window` or similar method & use that. #
def test_proposal_is_valid(proposal): from trivechaind import TrivechainDaemon import trivechainlib trivechaind = TrivechainDaemon.from_trivechain_conf(config.trivechain_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 proposal.name = 'valid-name' assert proposal.is_valid() is True proposal.name = ' mostly-valid-name' assert proposal.is_valid() is False proposal.name = 'also-mostly-valid-name ' assert proposal.is_valid() is False proposal.name = ' similarly-kinda-valid-name ' assert proposal.is_valid() is False proposal.name = 'dean miller 5493' assert proposal.is_valid() is False proposal.name = 'dean-millerà-5493' assert proposal.is_valid() is False proposal.name = 'dean-миллер-5493' assert proposal.is_valid() is False # binary gibberish proposal.name = trivechainlib.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 = 'tCa7rDMXs1KeqaqmcFoXxXMmwT9eq9r7oo' assert proposal.is_valid() is False proposal.payment_address = 'tRzq9nmzqzrLztMFj15LQzZQhvhrs7WyCN ' 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 Trivechain foundation multisig address... proposal.payment_address = 'sPnVo5H4HsWqYAc5aWHJxtAB3oGYa25nPz' assert proposal.is_valid() is False proposal.payment_address = 'tCa7rDMXs1KeqaqmcFoXxXMmwT9eq9r7oK' assert proposal.is_valid() is True proposal.payment_address = ' tCa7rDMXs1KeqaqmcFoXxXMmwT9eq9r7oK' assert proposal.is_valid() is False proposal.payment_address = 'tCa7rDMXs1KeqaqmcFoXxXMmwT9eq9r7oK ' assert proposal.is_valid() is False proposal.payment_address = ' tCa7rDMXs1KeqaqmcFoXxXMmwT9eq9r7oK ' assert proposal.is_valid() is False # 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 = ' http://bit.ly/1e1EYJv' assert proposal.is_valid() is False proposal.url = 'http://bit.ly/1e1EYJv ' assert proposal.is_valid() is False proposal.url = ' http://bit.ly/1e1EYJv ' assert proposal.is_valid() is False proposal.url = 'http://::12.34.56.78]/' assert proposal.is_valid() is False proposal.url = 'http://[::1/foo/bad]/bad' assert proposal.is_valid() is False proposal.url = 'http://gov.trivechain.com/dean-miller 5493' assert proposal.is_valid() is False proposal.url = 'http://trivechaincentralisé.org/dean-miller-5493' assert proposal.is_valid() is True proposal.url = 'http://trivechaincentralisé.org/dean-миллер-5493' 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 = trivechainlib.deserialise( '22687474703a2f2f5c75303330385c75303065665c75303362345c75303362315c75303266645c75303331345c625c75303134655c75303031615c75303139655c75303133365c75303264315c75303238655c75303364395c75303230665c75303363355c75303030345c75303336665c75303238355c75303165375c75303063635c75303139305c75303262615c75303239316a5c75303130375c75303362365c7530306562645c75303133335c75303335665c7530326562715c75303038655c75303332645c75303362645c75303064665c75303135654f365c75303237335c75303363645c7530333539275c75303165345c75303339615c75303365385c75303334345c75303130615c75303265662e5c75303231625c75303164356a5c75303232345c75303163645c75303336365c75303064625c75303339665c75303230305c75303337615c75303138395c75303263325c75303038345c75303066615c75303031335c75303233655c75303135345c75303165395c75303139635c75303239375c75303039355c75303038345c75303362305c7530306233435c75303135345c75303063665c75303163345c75303261335c75303362655c75303136305c75303139365c75303263665c75303131305c7530313031475c75303162645c75303338645c75303363325c75303138625c75303235625c75303266325c75303264635c75303139335c75303066665c75303066645c75303133625c75303234305c75303137615c75303062355c75303031645c75303238655c75303166315c75303232315c75303161615c75303265325c75303335625c75303333665c75303239345c75303335315c75303038345c75303339395c75303262385c75303132375c75303330357a5c75303263625c75303066305c75303062355c75303164335c75303338385c75303364385c75303130625c75303266325c75303137305c75303335315c75303030305c75303136385c75303039646d5c75303331315c75303236615c75303330375c75303332635c75303361635c665c75303363335c75303264365c75303238645c75303136395c7530323438635c75303163385c75303261355c75303164615c75303165375c75303337355c75303332645c7530333165755c75303131665c75303338375c75303135325c75303065325c75303135326c5c75303164325c75303164615c75303136645c75303061665c75303333375c75303264375c75303339375c75303139395c75303134635c75303165385c75303234315c75303336635c75303130645c75303230635c75303161615c75303339355c75303133315c75303064615c75303165615c75303336645c75303064325c75303337365c75303363315c75303132645c75303266305c75303064364f255c75303263635c75303162645c75303062385c75303238365c75303136395c75303337335c75303232335c75303336655c75303037665c75303062616b5c75303132365c75303233305c75303330645c75303362385c75303164355c75303166615c75303338395c75303062635c75303135325c75303334365c75303139645c75303135615c75303031395c75303061385c75303133615c75303338635c75303339625c75303261655c75303065395c75303362635c75303166385c75303031665c75303230615c75303263355c75303134335c75303361635c75303334355c75303236645c75303139365c75303362665c75303135615c75303137305c75303165395c75303231395c75303332665c75303232645c75303030365c75303066305c75303134665c75303337375c75303234325d5c75303164325c75303337655c75303265665c75303331395c75303261355c75303265385c75303338395c75303235645c75303334315c75303338395c7530323230585c75303062645c75303166365c75303238645c75303231375c75303066665c75303130385c75303331305c75303330335c75303031395c75303039635c75303363315c75303039615c75303334355c75303331305c75303162335c75303263315c75303132395c75303234335c75303038627c5c75303361335c75303261635c75303165655c75303030305c75303237615c75303038385c75303066355c75303232375c75303236635c75303236355c7530336336205c75303038615c7530333561787c735c75303336305c75303362655c75303235385c75303334345c75303264365c75303262355c75303361315c75303135345c75303131625c75303061625c75303038615c75303332655c75303238325c75303031393d5c75303263335c75303332655c75303163645c75303139305c75303231305c75303131365c75303334305c75303234665c75303162635c75303333645c75303135305c75303132335c75303233645c75303133345c75303062327a5c75303331635c75303136312a5c753032316522' ) assert proposal.is_valid() is False # reset proposal = Proposal(**orig.get_dict()) # ============================================================ # ensure proposal can't request negative trivechain # ============================================================ proposal.payment_amount = -1 assert proposal.is_valid() is False
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 dashd = DashDaemon.from_dash_conf(config.dash_conf) import misc # ============================================================================== # do stuff here pr = Proposal( name='RXCFunding', url='https://crypto.ba/t/rxc-blockchain-fundiranje/4110', payment_address='RLi1X4yqKwZjqzkqfk8f8FwjwxbwsRNRyw', payment_amount=48000, start_epoch=1606177383, end_epoch=1608769383, ) # sb = Superblock( # event_block_height = 62500, # payment_addresses = "yYe8KwyaUu5YswSYmB3q3ryx8XTUu9y7Ui|yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV", # payment_amounts = "5|3" # ) # TODO: make this a test, mock 'dashd' and tie a test block height to a # timestamp, ensure only unit testing a within_window method # # also, create the `within_window` or similar method & use that. #
def proposal(): from models import Proposal return Proposal()
def test_proposal_is_valid(proposal): from martkistd import MartkistDaemon import martkistlib martkistd = MartkistDaemon.from_martkist_conf(config.martkist_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 proposal.name = 'valid-name' assert proposal.is_valid() is True proposal.name = ' mostly-valid-name' assert proposal.is_valid() is False proposal.name = 'also-mostly-valid-name ' assert proposal.is_valid() is False proposal.name = ' similarly-kinda-valid-name ' assert proposal.is_valid() is False proposal.name = 'dean miller 5493' assert proposal.is_valid() is False proposal.name = 'dean-millerà-5493' assert proposal.is_valid() is False proposal.name = 'dean-миллер-5493' assert proposal.is_valid() is False # binary gibberish proposal.name = martkistlib.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 = 'TSTFEMEWWQICDWMSTWRAJ9WWVGNJZFFVFK' assert proposal.is_valid() is False proposal.payment_address = 'TSTfeMeWwQiCDwMSTWRaj9wwVGNjZFfvFK' assert proposal.is_valid() is False proposal.payment_address = '221 B Baker St., London, United Kingdom' assert proposal.is_valid() is False # TODO: multisig address proposal.payment_address = '7gnwGHt17heGpG9Crfeh4KGpYNFugPhJdh' assert proposal.is_valid() is False proposal.payment_address = 'TFcpmdvna59VuWdhCQQYsKE4jm6tUMeuEJ' assert proposal.is_valid() is True proposal.payment_address = ' TFcpmdvna59VuWdhCQQYsKE4jm6tUMeuEJ' assert proposal.is_valid() is False proposal.payment_address = 'TFcpmdvna59VuWdhCQQYsKE4jm6tUMeuEJ ' assert proposal.is_valid() is False proposal.payment_address = ' TFcpmdvna59VuWdhCQQYsKE4jm6tUMeuEJ ' assert proposal.is_valid() is False # 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 = ' http://bit.ly/1e1EYJv' assert proposal.is_valid() is False proposal.url = 'http://bit.ly/1e1EYJv ' assert proposal.is_valid() is False proposal.url = ' http://bit.ly/1e1EYJv ' assert proposal.is_valid() is False proposal.url = 'http://::12.34.56.78]/' assert proposal.is_valid() is False proposal.url = 'http://[::1/foo/bad]/bad' assert proposal.is_valid() is False proposal.url = 'http://martkistcentral.org/dean-miller 5493' assert proposal.is_valid() is False proposal.url = 'http://martkistcentralisé.org/dean-miller-5493' assert proposal.is_valid() is True proposal.url = 'http://martkistcentralisé.org/dean-миллер-5493' 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 = martkistlib.deserialise( '22687474703a2f2f5c75303330385c75303065665c75303362345c75303362315c75303266645c75303331345c625c75303134655c75303031615c75303139655c75303133365c75303264315c75303238655c75303364395c75303230665c75303363355c75303030345c75303336665c75303238355c75303165375c75303063635c75303139305c75303262615c75303239316a5c75303130375c75303362365c7530306562645c75303133335c75303335665c7530326562715c75303038655c75303332645c75303362645c75303064665c75303135654f365c75303237335c75303363645c7530333539275c75303165345c75303339615c75303365385c75303334345c75303130615c75303265662e5c75303231625c75303164356a5c75303232345c75303163645c75303336365c75303064625c75303339665c75303230305c75303337615c75303138395c75303263325c75303038345c75303066615c75303031335c75303233655c75303135345c75303165395c75303139635c75303239375c75303039355c75303038345c75303362305c7530306233435c75303135345c75303063665c75303163345c75303261335c75303362655c75303136305c75303139365c75303263665c75303131305c7530313031475c75303162645c75303338645c75303363325c75303138625c75303235625c75303266325c75303264635c75303139335c75303066665c75303066645c75303133625c75303234305c75303137615c75303062355c75303031645c75303238655c75303166315c75303232315c75303161615c75303265325c75303335625c75303333665c75303239345c75303335315c75303038345c75303339395c75303262385c75303132375c75303330357a5c75303263625c75303066305c75303062355c75303164335c75303338385c75303364385c75303130625c75303266325c75303137305c75303335315c75303030305c75303136385c75303039646d5c75303331315c75303236615c75303330375c75303332635c75303361635c665c75303363335c75303264365c75303238645c75303136395c7530323438635c75303163385c75303261355c75303164615c75303165375c75303337355c75303332645c7530333165755c75303131665c75303338375c75303135325c75303065325c75303135326c5c75303164325c75303164615c75303136645c75303061665c75303333375c75303264375c75303339375c75303139395c75303134635c75303165385c75303234315c75303336635c75303130645c75303230635c75303161615c75303339355c75303133315c75303064615c75303165615c75303336645c75303064325c75303337365c75303363315c75303132645c75303266305c75303064364f255c75303263635c75303162645c75303062385c75303238365c75303136395c75303337335c75303232335c75303336655c75303037665c75303062616b5c75303132365c75303233305c75303330645c75303362385c75303164355c75303166615c75303338395c75303062635c75303135325c75303334365c75303139645c75303135615c75303031395c75303061385c75303133615c75303338635c75303339625c75303261655c75303065395c75303362635c75303166385c75303031665c75303230615c75303263355c75303134335c75303361635c75303334355c75303236645c75303139365c75303362665c75303135615c75303137305c75303165395c75303231395c75303332665c75303232645c75303030365c75303066305c75303134665c75303337375c75303234325d5c75303164325c75303337655c75303265665c75303331395c75303261355c75303265385c75303338395c75303235645c75303334315c75303338395c7530323230585c75303062645c75303166365c75303238645c75303231375c75303066665c75303130385c75303331305c75303330335c75303031395c75303039635c75303363315c75303039615c75303334355c75303331305c75303162335c75303263315c75303132395c75303234335c75303038627c5c75303361335c75303261635c75303165655c75303030305c75303237615c75303038385c75303066355c75303232375c75303236635c75303236355c7530336336205c75303038615c7530333561787c735c75303336305c75303362655c75303235385c75303334345c75303264365c75303262355c75303361315c75303135345c75303131625c75303061625c75303038615c75303332655c75303238325c75303031393d5c75303263335c75303332655c75303163645c75303139305c75303231305c75303131365c75303334305c75303234665c75303162635c75303333645c75303135305c75303132335c75303233645c75303133345c75303062327a5c75303331635c75303136312a5c753032316522' ) assert proposal.is_valid() is False # reset proposal = Proposal(**orig.get_dict()) # ============================================================ # ensure proposal can't request negative martkist # ============================================================ proposal.payment_amount = -1 assert proposal.is_valid() is False
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 quantisnetd import quantisnetDaemon import quantisnetlib from decimal import Decimal quantisnetd = quantisnetDaemon.from_quantisnet_conf(config.quantisnet_conf) import misc # ============================================================================== # do stuff here pr = Proposal( name='proposal7', url='https://testproposal.com/proposal7', payment_address='QM1sn2HmMcuVWtRXLbYP8RvwsZfGCK9tD1', payment_amount=39.23, start_epoch=1483250400, end_epoch=1491022800, ) # sb = Superblock( # event_block_height = 62500, # payment_addresses = "QM1sn2HmMcuVWtRXLbYP8RvwsZfGCK9tD1|QMFF2uEjWCRMS8U8pjjcNQXxaHgHJhm5wL", # payment_amounts = "5|3" # ) # TODO: make this a test, mock 'quantisnetd' and tie a test block height to a # timestamp, ensure only unit testing a within_window method # # also, create the `within_window` or similar method & use that. #