예제 #1
0
def governanceblock():
    sb = GovernanceBlock(
        event_block_height=62500,
        payment_addresses=
        'yYe8KwyaUu5YswSYmB3q3ryx8XTUu9y7Ui|yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV',
        payment_amounts='5|3',
        proposal_hashes=
        'e8a0057914a2e1964ae8a945c4723491caae2077a90a00a2aabee22b40081a87|d1ce73527d7cd6f2218f8ca893990bc7d5c6b9334791ce7973bfa22f155f826e',
    )
    return sb
예제 #2
0
def test_serialisable_fields():
    s1 = [
        'event_block_height', 'payment_addresses', 'payment_amounts',
        'proposal_hashes'
    ]
    s2 = GovernanceBlock.serialisable_fields()

    s1.sort()
    s2.sort()

    assert s2 == s1
예제 #3
0
def test_deterministic_governanceblock_selection(go_list_governanceblocks):
    from genesisd import GenesisDaemon
    genesisd = GenesisDaemon.from_genesis_conf(config.genesis_conf)

    for item in go_list_governanceblocks:
        (go, subobj) = GovernanceObject.import_gobject_from_genesisd(
            genesisd, item)

    # highest hash wins if same -- so just order by hash
    sb = GovernanceBlock.find_highest_deterministic(
        '542f4433e438bdd64697b8381fda1a7a9b7a111c3a4e32fad524d1821d820394')
    assert sb.object_hash == 'bc2834f357da7504138566727c838e6ada74d079e63b6104701f4f8eb05dae36'
예제 #4
0
def create_governanceblock(proposals, event_block_height, budget_max,
                           sb_epoch_time, maxgovobjdatasize):
    from models import GovernanceBlock, GovernanceObject, Proposal
    from constants import GOVERNANCEBLOCK_FUDGE_WINDOW

    # don't create an empty governanceblock
    if (len(proposals) == 0):
        printdbg("No proposals, cannot create an empty governanceblock.")
        return None

    budget_allocated = Decimal(0)
    fudge = GOVERNANCEBLOCK_FUDGE_WINDOW  # fudge-factor to allow for slightly incorrect estimates

    payments = []

    for proposal in proposals:
        fmt_string = "name: %s, rank: %4d, hash: %s, amount: %s <= %s"

        # skip proposals that are too expensive...
        if (budget_allocated + proposal.payment_amount) > budget_max:
            printdbg(fmt_string % (
                proposal.name,
                proposal.rank,
                proposal.object_hash,
                proposal.payment_amount,
                "skipped (blows the budget)",
            ))
            continue

        # skip proposals if the SB isn't within the Proposal time window...
        window_start = proposal.start_epoch - fudge
        window_end = proposal.end_epoch + fudge

        printdbg("\twindow_start: %s" % epoch2str(window_start))
        printdbg("\twindow_end: %s" % epoch2str(window_end))
        printdbg("\tsb_epoch_time: %s" % epoch2str(sb_epoch_time))

        if (sb_epoch_time < window_start or sb_epoch_time > window_end):
            printdbg(fmt_string % (
                proposal.name,
                proposal.rank,
                proposal.object_hash,
                proposal.payment_amount,
                "skipped (SB time is outside of Proposal window)",
            ))
            continue

        printdbg(fmt_string % (
            proposal.name,
            proposal.rank,
            proposal.object_hash,
            proposal.payment_amount,
            "adding",
        ))

        payment = {
            'address': proposal.payment_address,
            'amount': "{0:.8f}".format(proposal.payment_amount),
            'proposal': "{}".format(proposal.object_hash)
        }

        # calculate current sb data size
        sb_temp = GovernanceBlock(
            event_block_height=event_block_height,
            payment_addresses='|'.join([pd['address'] for pd in payments]),
            payment_amounts='|'.join([pd['amount'] for pd in payments]),
            proposal_hashes='|'.join([pd['proposal'] for pd in payments]))
        data_size = len(sb_temp.genesisd_serialise())

        if data_size > maxgovobjdatasize:
            printdbg("MAX_GOVERNANCE_OBJECT_DATA_SIZE limit reached!")
            break

        # else add proposal and keep track of total budget allocation
        budget_allocated += proposal.payment_amount
        payments.append(payment)

    # don't create an empty governanceblock
    if not payments:
        printdbg("No proposals made the cut!")
        return None

    # 'payments' now contains all the proposals for inclusion in the
    # GovernanceBlock, but needs to be sorted by proposal hash descending
    payments.sort(key=lambda k: k['proposal'], reverse=True)

    sb = GovernanceBlock(
        event_block_height=event_block_height,
        payment_addresses='|'.join([pd['address'] for pd in payments]),
        payment_amounts='|'.join([pd['amount'] for pd in payments]),
        proposal_hashes='|'.join([pd['proposal'] for pd in payments]),
    )
    printdbg("generated governanceblock: %s" % sb.__dict__)

    return sb
예제 #5
0
def setup():
    # clear tables first...
    Vote.delete().execute()
    Proposal.delete().execute()
    GovernanceBlock.delete().execute()
    GovernanceObject.delete().execute()
예제 #6
0
def test_governanceblock_is_valid(governanceblock):
    from genesisd import GenesisDaemon
    genesisd = GenesisDaemon.from_genesis_conf(config.genesis_conf)

    orig = GovernanceBlock(**governanceblock.get_dict())  # make a copy

    # original as-is should be valid
    assert orig.is_valid() is True

    # mess with payment amounts
    governanceblock.payment_amounts = '7|yyzx'
    assert governanceblock.is_valid() is False

    governanceblock.payment_amounts = '7,|yzx'
    assert governanceblock.is_valid() is False

    governanceblock.payment_amounts = '7|8'
    assert governanceblock.is_valid() is True

    governanceblock.payment_amounts = ' 7|8'
    assert governanceblock.is_valid() is False

    governanceblock.payment_amounts = '7|8 '
    assert governanceblock.is_valid() is False

    governanceblock.payment_amounts = ' 7|8 '
    assert governanceblock.is_valid() is False

    # reset
    governanceblock = GovernanceBlock(**orig.get_dict())
    assert governanceblock.is_valid() is True

    # mess with payment addresses
    governanceblock.payment_addresses = 'yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV|1234 Anywhere ST, Chicago, USA'
    assert governanceblock.is_valid() is False

    # leading spaces in payment addresses
    governanceblock.payment_addresses = ' yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV'
    governanceblock.payment_amounts = '5.00'
    assert governanceblock.is_valid() is False

    # trailing spaces in payment addresses
    governanceblock.payment_addresses = 'yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV '
    governanceblock.payment_amounts = '5.00'
    assert governanceblock.is_valid() is False

    # leading & trailing spaces in payment addresses
    governanceblock.payment_addresses = ' yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV '
    governanceblock.payment_amounts = '5.00'
    assert governanceblock.is_valid() is False

    # single payment addr/amt is ok
    governanceblock.payment_addresses = 'yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV'
    governanceblock.payment_amounts = '5.00'
    assert governanceblock.is_valid() is True

    # ensure number of payment addresses matches number of payments
    governanceblock.payment_addresses = 'yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV'
    governanceblock.payment_amounts = '37.00|23.24'
    assert governanceblock.is_valid() is False

    governanceblock.payment_addresses = 'yYe8KwyaUu5YswSYmB3q3ryx8XTUu9y7Ui|yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV'
    governanceblock.payment_amounts = '37.00'
    assert governanceblock.is_valid() is False

    # ensure amounts greater than zero
    governanceblock.payment_addresses = 'yTC62huR4YQEPn9AJHjnQxxreHSbgAoatV'
    governanceblock.payment_amounts = '-37.00'
    assert governanceblock.is_valid() is False

    # reset
    governanceblock = GovernanceBlock(**orig.get_dict())
    assert governanceblock.is_valid() is True

    # mess with proposal hashes
    governanceblock.proposal_hashes = '7|yyzx'
    assert governanceblock.is_valid() is False

    governanceblock.proposal_hashes = '7,|yyzx'
    assert governanceblock.is_valid() is False

    governanceblock.proposal_hashes = '0|1'
    assert governanceblock.is_valid() is False

    governanceblock.proposal_hashes = '0000000000000000000000000000000000000000000000000000000000000000|1111111111111111111111111111111111111111111111111111111111111111'
    assert governanceblock.is_valid() is True

    # reset
    governanceblock = GovernanceBlock(**orig.get_dict())
    assert governanceblock.is_valid() is True
예제 #7
0
def attempt_governanceblock_creation(genesisd):
    import genesislib

    if not genesisd.is_masternode():
        print("We are not a Masternode... can't submit governanceblocks!")
        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* governanceblocks at the given event_block_height?
    # have we voted FUNDING=YES for a governanceblock for this specific event_block_height?

    event_block_height = genesisd.next_governanceblock_height()

    if GovernanceBlock.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 GovernanceBlock.at_height(event_block_height):
            if not sb.voted_on(signal=VoteSignals.funding):
                sb.vote(genesisd, VoteSignals.funding, VoteOutcomes.no)

        # now return, we're done
        return

    if not genesisd.is_govobj_maturity_phase():
        printdbg(
            "Not in maturity phase yet -- will not attempt GovernanceBlock")
        return

    proposals = Proposal.approved_and_ranked(
        proposal_quorum=genesisd.governance_quorum(),
        next_governanceblock_max_budget=genesisd.
        next_governanceblock_max_budget())
    budget_max = genesisd.get_governanceblock_budget_allocation(
        event_block_height)
    sb_epoch_time = genesisd.block_height_to_epoch(event_block_height)

    maxgovobjdatasize = genesisd.govinfo['maxgovobjdatasize']
    sb = genesislib.create_governanceblock(proposals, event_block_height,
                                           budget_max, sb_epoch_time,
                                           maxgovobjdatasize)
    if not sb:
        printdbg("No governanceblock created, sorry. Returning.")
        return

    # find the deterministic SB w/highest object_hash in the DB
    dbrec = GovernanceBlock.find_highest_deterministic(sb.hex_hash())
    if dbrec:
        dbrec.vote(genesisd, VoteSignals.funding, VoteOutcomes.yes)

        # any other blocks which match the sb_hash are duplicates, delete them
        for sb in GovernanceBlock.select().where(
                GovernanceBlock.sb_hash == sb.hex_hash()):
            if not sb.voted_on(signal=VoteSignals.funding):
                sb.vote(genesisd, VoteSignals.delete, VoteOutcomes.yes)

        printdbg(
            "VOTED FUNDING FOR SB! We're done here 'til next governanceblock cycle."
        )
        return
    else:
        printdbg("The correct governanceblock wasn't found on the network...")

    # if we are the elected masternode...
    if (genesisd.we_are_the_winner()):
        printdbg("we are the winner! Submit SB to network")
        sb.submit(genesisd)