Esempio n. 1
0
def test_superblock_size_limit(go_list_proposals):
    import chaincoinlib
    import misc
    from chaincoind import ChaincoinDaemon
    chaincoind = ChaincoinDaemon.from_chaincoin_conf(config.chaincoin_conf)
    for item in go_list_proposals:
        (go, subobj) = GovernanceObject.import_gobject_from_chaincoind(chaincoind, item)

    max_budget = 60
    prop_list = Proposal.approved_and_ranked(proposal_quorum=1, next_superblock_max_budget=max_budget)

    # mock maxgovobjdatasize by setting equal to the size of a trigger
    # (serialized) if only the first proposal had been included... anything
    # larger should break the limit
    single_proposal_sb = Superblock(
        event_block_height=72000,
        payment_addresses=prop_list[0].payment_address,
        payment_amounts="{0:.8f}".format(prop_list[0].payment_amount),
        proposal_hashes=prop_list[0].object_hash,
    )
    maxgovobjdatasize = len(single_proposal_sb.serialise())

    # now try and create a Superblock with the entire proposal list
    sb = chaincoinlib.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 size limit
    assert sb.event_block_height == 72000
    assert sb.payment_addresses == 'ZHJV7jhBWgaB1uxazbVsnQU5HUDAqX14Bz|ZH6bt95skGVco2t3gRuHggcSUrtRZ5BUsr'
    assert sb.payment_amounts == '315.75000000|21.05000000'
    assert sb.proposal_hashes == '7fa2798fee8ea74c3a369db72ae872096bd4e4714f1f5027c730ccfbf58aac02|d1ce73527d7cd6f2218f8ca893990bc7d5c6b9334791ce7973bfa22f155f826e'

    assert sb.hex_hash() == 'bb3f33ccf95415c396bd09d35325dbcbc7b067010d51c7ccf772a9e839c1e414'
Esempio n. 2
0
def test_superblock_size_limit(go_list_proposals):
    import exiliumlib
    import misc
    from exiliumd import ExiliumDaemon
    exiliumd = ExiliumDaemon.from_exilium_conf(config.exilium_conf)
    for item in go_list_proposals:
        (go, subobj) = GovernanceObject.import_gobject_from_exiliumd(
            exiliumd, item)

    max_budget = 60
    prop_list = Proposal.approved_and_ranked(
        proposal_quorum=1, next_superblock_max_budget=max_budget)

    # mock maxgovobjdatasize by setting equal to the size of a trigger
    # (serialized) if only the first proposal had been included... anything
    # larger should break the limit
    single_proposal_sb = Superblock(
        event_block_height=72000,
        payment_addresses=prop_list[0].payment_address,
        payment_amounts="{0:.8f}".format(prop_list[0].payment_amount),
        proposal_hashes=prop_list[0].object_hash,
    )
    maxgovobjdatasize = len(single_proposal_sb.serialise())

    # now try and create a Superblock with the entire proposal list
    sb = exiliumlib.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 size 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'
Esempio n. 3
0
def create_superblock(proposals, event_block_height, budget_max,
                      sb_epoch_time):
    from models import Superblock, GovernanceObject, Proposal
    from constants import SUPERBLOCK_FUDGE_WINDOW
    import copy

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

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

    payments_list = []

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

        temp_payments_list = copy.deepcopy(payments_list)
        temp_payments_list.append(payment)

        # calculate size of proposed Superblock
        sb_temp = Superblock(event_block_height=event_block_height,
                             payment_addresses='|'.join(
                                 [pd['address'] for pd in temp_payments_list]),
                             payment_amounts='|'.join(
                                 [pd['amount'] for pd in temp_payments_list]),
                             proposal_hashes='|'.join([
                                 pd['proposal'] for pd in temp_payments_list
                             ]))
        proposed_sb_size = len(sb_temp.serialise())

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

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

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

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

    return sb