예제 #1
0
    def test_calculate(self):
        rewards = []
        ratios = [0.25, 0.05, 0.3, 0.15, 0.25]
        total_reward = 1000

        for i, ratio in enumerate(ratios, start=1):
            rl0 = RewardLog(address="addr" + str(i), type="D", staking_balance=total_reward * ratio, current_balance=0)
            rl0.ratio0 = ratio
            rewards.append(rl0)

        excluded_set = {"addr1"}

        phase1 = CalculatePhase1(excluded_set)
        new_rewards, new_total_reward = phase1.calculate(rewards, total_reward)

        self.assertEqual(total_reward * (1 - 0.25), new_total_reward)

        # check new ratios sum up to 1
        # old and new reward amount is the same
        ratio_sum = 0.0

        self.assertTrue(new_rewards)

        # first item is excluded
        # compare rest of the items
        for pr_new, ratio0 in zip(new_rewards[1:], ratios[1:]):
            ratio_sum += pr_new.ratio1

            self.assertAlmostEqual(ratio0 * total_reward, pr_new.ratio1 * new_total_reward, delta=0.000001)

        self.assertEqual(1.0, ratio_sum)
def test_attempt_single_batch_tz(sign, request_url, request_url_post):
    network_config = {"BLOCK_TIME_IN_SEC": 60, "MINIMAL_BLOCK_DELAY": 30}
    batch_payer = BatchPayer(
        node_url="node_addr",
        pymnt_addr=TEST_TZ_ADDRESS,
        clnt_mngr=ClientManager(
            node_endpoint=PUBLIC_NODE_URL[CURRENT_TESTNET],
            signer_endpoint=PRIVATE_SIGNER_URL,
        ),
        delegator_pays_ra_fee=True,
        delegator_pays_xfer_fee=True,
        network_config=network_config,
        plugins_manager=MagicMock(),
        dry_run=False,
    )
    batch_payer.base_counter = 0
    reward_log = RewardLog(
        address=TEST_TZ_ADDRESS,
        type="D",
        staking_balance=80,
        current_balance=100,
    )

    reward_log.adjusted_amount = 15577803
    reward_log.skipped = False

    opt_counter = OpCounter()
    status, operation_hash, _ = batch_payer.attempt_single_batch([reward_log],
                                                                 opt_counter,
                                                                 dry_run=True)
    assert status == PaymentStatus.DONE
    assert operation_hash is None
    assert reward_log.delegator_transaction_fee == TZTX_FEE
    assert opt_counter.counter == 3209358
예제 #3
0
def test_simulate_single_operation():
    default_fee = TZTX_FEE
    network_config = {"BLOCK_TIME_IN_SEC": 60, "MINIMAL_BLOCK_DELAY": 30}
    batch_payer = BatchPayer(
        node_url="node_addr",
        pymnt_addr="tz1234567890123456789012345678901234",
        clnt_mngr=ClientManager(
            node_endpoint=PUBLIC_NODE_URL[CURRENT_TESTNET],
            signer_endpoint=PRIVATE_SIGNER_URL,
        ),
        delegator_pays_ra_fee=True,
        delegator_pays_xfer_fee=True,
        network_config=network_config,
        plugins_manager=MagicMock(),
        dry_run=False,
    )
    batch_payer.base_counter = 0
    reward_log = RewardLog(
        address="KT1P3Y1mkGASzuJqLh7uGuQEvHatztGuQRgC",
        type="D",
        staking_balance=0,
        current_balance=0,
    )
    reward_log.amount = 15577803
    reward_log.skipped = False
    simulation_status, simulation_results = batch_payer.simulate_single_operation(
        reward_log, reward_log.amount, "hash", "unittest")
    assert PaymentStatus.DONE == simulation_status
    consumed_gas, tx_fee, storage = simulation_results
    assert 150 == consumed_gas
    assert 410 == default_fee + consumed_gas * MUTEZ_PER_GAS_UNIT
    assert int == type(storage)  # type of storage should be int
    assert 24 == storage
예제 #4
0
    def test_calculate(self):
        rewards = []
        ratios = {
            "addr1": 0.25,
            "addr2": 0.05,
            "addr3": 0.3,
            "addr4": 0.15,
            "addr5": 0.25,
        }
        total_reward = 1000

        for i, addr in enumerate(ratios, start=1):
            rl0 = RewardLog(
                address="addr" + str(i),
                type="D",
                staking_balance=total_reward * ratios[addr],
                current_balance=0,
            )
            rl0.ratio1 = ratios[addr]
            rewards.append(rl0)

        rewards.append(RewardLog("addrdummy", "D", 0, 0).skip("skipped for testing", 2))

        excluded_set = {"addr1"}

        phase2 = CalculatePhase2(excluded_set)
        new_rewards, new_total_reward = phase2.calculate(rewards, total_reward)

        # new_total_reward = total_reward
        self.assertEqual(total_reward, new_total_reward)

        # check new ratios sum up to 1
        # old and new reward amount is the same
        for pr_new in new_rewards:
            if pr_new.skipped:
                continue
            ratio1 = ratios[pr_new.address]

            # actual and returning ratio1
            self.assertEqual(ratio1, pr_new.ratio1)

            # difference between new amount and old amount is
            # C+C*(a/1-a)-C = C*(a/1-a)
            # -->
            # C'*Total = C *Total + C*(a/1-a)*Total
            self.assertAlmostEqual(
                ratio1 * total_reward,
                pr_new.ratio2 * new_total_reward
                - ratio1 * (0.25 / 0.75) * new_total_reward,
                delta=0.000001,
            )
        ratio_sum = 0.0
        for pr_new in new_rewards:
            if pr_new.ratio2 is None:
                continue
            ratio_sum += pr_new.ratio2

        self.assertEqual(1.0, ratio_sum)
    def test_calculate(self):
        rewards = []
        ratios = [0.25, 0.05, 0.3, 0.15, 0.25]
        total_reward = 1000

        for i, ratio in enumerate(ratios, start=1):
            rl0 = RewardLog(
                address="addr" + str(i),
                type="D",
                staking_balance=total_reward * ratio,
                current_balance=0,
            )
            rl0.ratio = ratio
            rl0.ratio3 = ratio
            rewards.append(rl0)

        rewards[0].type = TYPE_OWNERS_PARENT
        rewards[1].type = TYPE_FOUNDERS_PARENT

        rewards.append(
            RewardLog("addrdummy", "D", 0, 0).skip("skipped for testing", 3))

        founders_map = {"addr1": 0.4, "addr2": 0.6}
        owners_map = {"addr1": 0.6, "addr2": 0.4}

        phase4 = CalculatePhase4(founders_map, owners_map)
        new_rewards, new_total_reward = phase4.calculate(rewards, total_reward)

        # new_total_reward = total_reward
        self.assertEqual(total_reward, new_total_reward)

        # check new ratios sum up to 1
        # old and new reward amount is the same
        ratio_sum = 0.0

        # filter out skipped records
        new_rewards = list(rl for rl in new_rewards if not rl.skipped)

        # 2 owner, 2 founders and 3 delegators
        self.assertEqual(7, len(new_rewards))

        founder_ratio = 0.0
        owner_ratio = 0.0
        for rl4 in new_rewards:
            if rl4.skipped:
                continue

            if rl4.type == TYPE_FOUNDER:
                founder_ratio += rl4.ratio4
            if rl4.type == TYPE_OWNER:
                owner_ratio += rl4.ratio4

            ratio_sum += rl4.ratio4

        self.assertAlmostEqual(1.0, ratio_sum, delta=1e-6)
        self.assertAlmostEqual(0.25, owner_ratio, delta=1e-6)
        self.assertAlmostEqual(0.05, founder_ratio, delta=1e-6)
예제 #6
0
    def test_calculate(self):
        rewards = []
        ratios = [0.25, 0.05, 0.3, 0.15, 0.25]
        total_reward = 1000

        for i, ratio in enumerate(ratios, start=1):
            rl0 = RewardLog(
                address="addr" + str(i),
                type="D",
                staking_balance=total_reward * ratio,
                current_balance=0,
            )
            rl0.ratio = ratio
            rl0.ratio2 = ratio
            rewards.append(rl0)

        rewards.append(
            RewardLog("addrdummy", "D", 0, 0).skip("skipped for testing", 2))

        excluded_set = {"addr1"}

        fee_calculator = ServiceFeeCalculator(set(), dict(), 20)  # 20% fee
        phase3 = CalculatePhase3(fee_calculator, excluded_set)

        new_rewards, new_total_reward = phase3.calculate(rewards, total_reward)

        # filter out skipped records
        new_rewards = list(rl for rl in new_rewards if not rl.skipped)

        # new_total_reward = total_reward
        self.assertEqual(total_reward, new_total_reward)

        # check new ratios sum up to 1
        # old and new reward amount is the same
        ratio_sum = 0.0
        service_fee_ratio_sum = 0.0

        founder_pl = None
        for rl3 in new_rewards:
            if rl3.skipped:
                continue

            if rl3.type == TYPE_FOUNDERS_PARENT:
                founder_pl = rl3

            ratio_sum += rl3.ratio3
            service_fee_ratio_sum += rl3.service_fee_ratio

        self.assertAlmostEqual(1.0, ratio_sum, delta=ALMOST_ZERO)
        self.assertAlmostEqual(0.15, service_fee_ratio_sum, delta=ALMOST_ZERO)
        self.assertAlmostEqual(0.4, founder_pl.ratio3, delta=ALMOST_ZERO)
    def calculate(self, reward_logs):
        # if address is in address destination dictionary;
        # then set payment address to mapped address value
        for rl in self.filterskipped(reward_logs):
            rl.ratio6 = rl.ratio

        address_set = set(rl.paymentaddress
                          for rl in self.filterskipped(reward_logs))
        payment_address_list_dict = {addr: [] for addr in address_set}

        # group payments by paymentaddress
        for rl in self.filterskipped(reward_logs):
            payment_address_list_dict[rl.paymentaddress].append(rl)

        reward_data6 = []
        for rl in self.iterateskipped(reward_logs):
            reward_data6.append(rl)

        for addr, rl_list in payment_address_list_dict.items():
            if len(rl_list) > 1:
                total_staking_balance = sum(
                    [rl.staking_balance for rl in rl_list])
                total_current_balance = sum(
                    [rl.current_balance for rl in rl_list])
                total_ratio = sum([rl.ratio for rl in rl_list])
                total_payment_amount = sum([rl.amount for rl in rl_list])
                total_adjusted_payment_amount = sum(
                    [rl.adjusted_amount for rl in rl_list])
                total_adjustment = sum([rl.adjustment for rl in rl_list])
                total_service_fee_amount = sum(
                    [rl.service_fee_amount for rl in rl_list])
                total_service_fee_ratio = sum(
                    [rl.service_fee_ratio for rl in rl_list])

                merged = RewardLog(addr, TYPE_MERGED, total_staking_balance,
                                   total_current_balance)
                merged.ratio = total_ratio
                merged.amount = total_payment_amount
                merged.adjusted_amount = total_adjusted_payment_amount
                merged.adjustment = total_adjustment
                merged.service_fee_amount = total_service_fee_amount
                merged.service_fee_ratio = total_service_fee_ratio
                merged.service_fee_rate = 0
                merged.parents = rl_list

                reward_data6.append(merged)
            else:
                reward_data6.append(rl_list[0])

        return reward_data6
    def test_calculate(self):
        rewards = []
        ratios = [0.25, 0.05, 0.3, 0.15, 0.25]
        total_reward = 1000

        for i, ratio in enumerate(ratios, start=1):
            rl0 = RewardLog(
                address="addr" + str(i),
                type="D",
                staking_balance=total_reward * ratio,
                current_balance=0,
            )
            rl0.ratio = ratio
            rl0.ratio4 = ratio
            rewards.append(rl0)

        rewards.append(RewardLog("addrdummy", "D", 0, 0).skip("skipped for testing", 4))

        phaseMapping = CalculatePhaseMapping()
        new_rewards = phaseMapping.calculate(rewards, {"addr2": "addr1"})

        # filter out skipped records
        new_rewards = list(rl for rl in new_rewards if not rl.skipped)

        # check new ratios sum up to 1
        # old and new reward amount is the same
        ratio_sum = sum(rl.ratio5 for rl in new_rewards)

        # payment address for address2 is address1
        payment_address_set = set(rl.paymentaddress for rl in new_rewards)
        self.assertEqual(4, len(payment_address_set))

        self.assertAlmostEqual(1.0, ratio_sum, delta=ALMOST_ZERO)

        # ratio of records having payment address addr1 must be 0.30 (0.25+0.05)
        self.assertAlmostEqual(
            0.30,
            sum(
                rl.ratio
                for rl in list(
                    filter(
                        lambda rl: rl.paymentaddress == "addr1",
                        filter(lambda rl: not rl.skipped, new_rewards),
                    )
                )
            ),
            delta=ALMOST_ZERO,
        )
    def calculate(self, reward_logs=None, total_reward_amount=None):
        """
        :param reward_logs: Nothing is expected. This value is not used. reward_logs are generated from provider object.
        :param total_reward_amount: Nothing is expected. This value is not used. total amount is calculated in calling function.
        :return: tuple (reward_logs, total reward amount)

        reward_logs is a list of RewardLog objects. Last item is owners_parent record.
        total_reward equals to sum( delegator rewards + owners_parent rewards )
        """

        ratio_sum = 0.0
        total_delegator_balance = 0
        reward_logs = []
        delegate_staking_balance = self.reward_provider_model.delegate_staking_balance
        delegators_balance_dict = self.reward_provider_model.delegator_balance_dict

        # calculate how rewards will be distributed
        # ratio is stake/total staking balance
        # total of ratios must be 1

        for address, delegator_info in delegators_balance_dict.items():

            staking_balance = delegator_info["staking_balance"]
            current_balance = delegator_info["current_balance"]
            originaladdress = (delegator_info["originaladdress"] if
                               "originaladdress" in delegator_info else None)
            total_delegator_balance += staking_balance

            ratio = staking_balance / delegate_staking_balance
            reward_item = RewardLog(
                address=address,
                type=reward_log.TYPE_DELEGATOR,
                staking_balance=staking_balance,
                current_balance=current_balance,
                originaladdress=originaladdress,
            )
            reward_item.ratio = ratio
            reward_item.ratio0 = reward_item.ratio

            ratio_sum += ratio

            reward_logs.append(reward_item)

        owners_rl = RewardLog(
            address=reward_log.TYPE_OWNERS_PARENT,
            type=reward_log.TYPE_OWNERS_PARENT,
            staking_balance=delegate_staking_balance - total_delegator_balance,
            current_balance=0,
        )
        owners_rl.ratio = 1 - ratio_sum
        owners_rl.ratio0 = owners_rl.ratio

        reward_logs.append(owners_rl)

        return reward_logs
예제 #10
0
    def test_calculate(self):
        rewards = []
        ratios = [0.25, 0.05, 0.3, 0.15, 0.25]
        total_reward = 1000

        for i, ratio in enumerate(ratios, start=1):
            rl0 = RewardLog(address="addr" + str(i),
                            type="D",
                            balance=total_reward * ratio)
            rl0.ratio4 = ratio
            rewards.append(rl0)

        rewards[0].address = "addr1"
        rewards[1].address = "addr1"

        rewards.append(
            RewardLog("addrdummy", "D", 0).skip("skipped for testing", 4))

        phase5 = CalculatePhase5()

        new_rewards, new_total_reward = phase5.calculate(rewards, total_reward)

        # filter out skipped records
        new_rewards = list(rl for rl in new_rewards if not rl.skipped)

        # new_total_reward = total_reward
        self.assertEqual(total_reward, new_total_reward)

        # check new ratios sum up to 1
        # old and new reward amount is the same
        ratio_sum = sum(rl.ratio5 for rl in new_rewards)

        # 2 records are merged
        self.assertEqual(4, len(new_rewards))

        self.assertAlmostEqual(1.0, ratio_sum, delta=1e-6)

        # ratio of merged record must be 0.30 (0.25+0.05)
        self.assertAlmostEqual(0.30,
                               list(
                                   filter(
                                       lambda rl: rl.type == TYPE_MERGED,
                                       filter(lambda rl: not rl.skipped,
                                              new_rewards)))[0].ratio5,
                               delta=1e-6)
    def from_payment_csv_dict_row(row, cycle):
        reward_log = RewardLog(row["address"], row["type"], 0, 0)
        reward_log.cycle = cycle
        reward_log.adjusted_amount = int(row["amount"])
        reward_log.hash = None if row["hash"] == "None" else row["hash"]
        reward_log.paid = PaymentStatus[str(row["paid"]).upper()]
        reward_log.desc = str(row["description"])

        return reward_log
예제 #12
0
    def FromPaymentCSVDictRow(self, row, cyle):
        rl = RewardLog(row["address"], row["type"], None)
        rl.cycle = cyle
        rl.amount = int(row["amount"])
        rl.hash = None if row["hash"] == 'None' else row["hash"]
        rl.balance = 0 if rl.balance == None else rl.balance
        rl.paid = PaymentStatus(int(row["paid"]))
        # rl.child = None if row["child"] == 'None' else row["child"]

        return rl
예제 #13
0
    def from_payment_csv_dict_row(row, cycle):
        rl = RewardLog(row["address"], row["type"], 0, 0)
        rl.cycle = cycle
        rl.amount = int(row["amount"])
        rl.hash = None if row["hash"] == "None" else row["hash"]
        rl.paid = PaymentStatus(int(row["paid"]))

        return rl
    def FromPaymentCSVDictRow(self, row, cycle):
        rl = RewardLog(row["address"], row["type"], 0, 0)
        rl.cycle = cycle
        rl.amount = int(row["amount"])
        rl.hash = None if row["hash"] == 'None' else row["hash"]
        rl.paid = PaymentStatus(int(row["paid"]))

        return rl
예제 #15
0
def test_simulate_single_operation():
    config = configparser.ConfigParser()
    assert os.path.isfile(FEE_INI) is True
    config.read(FEE_INI)
    default_fee = int(config["KTTX"]["fee"])
    network_config = {"BLOCK_TIME_IN_SEC": 64}
    batch_payer = BatchPayer(
        node_url="node_addr",
        pymnt_addr="tz1234567890123456789012345678901234",
        clnt_mngr=ClientManager(
            node_endpoint="https://testnet-tezos.giganode.io:443",
            signer_endpoint="http://127.0.0.1:6732",
        ),
        delegator_pays_ra_fee=True,
        delegator_pays_xfer_fee=True,
        network_config=network_config,
        plugins_manager=MagicMock(),
        dry_run=False,
    )
    batch_payer.base_counter = 0
    reward_log = RewardLog(
        address="KT1P3Y1mkGASzuJqLh7uGuQEvHatztGuQRgC",
        type="D",
        staking_balance=0,
        current_balance=0,
    )
    reward_log.amount = 15577803
    reward_log.skipped = False
    simulation_status, simulation_results = batch_payer.simulate_single_operation(
        reward_log, reward_log.amount, "hash", "unittest")
    assert PaymentStatus.DONE == simulation_status
    consumed_gas, tx_fee, storage = simulation_results
    assert 150 == consumed_gas
    assert 589 == default_fee + consumed_gas * MUTEZ_PER_GAS_UNIT
    assert int == type(storage)  # type of storage should be int
    assert 24 == storage
예제 #16
0
    def calculate(self, reward_data2, total_amount):

        new_rewards = []
        total_excluded_ratio = 0.0

        for rl2 in self.iterateskipped(reward_data2):
            # move skipped records to next phase
            new_rewards.append(rl2)

        # exclude requested items
        for rl2 in self.filterskipped(reward_data2):
            if rl2.address in self.excluded_set:
                rl2.skip(desc=BY_CONFIGURATION, phase=self.phase)
                new_rewards.append(rl2)
                total_excluded_ratio += rl2.ratio
            elif (
                MIN_DELEGATION_KEY in self.excluded_set
                and rl2.staking_balance < self.min_delegation_amount
            ):
                rl2.skip(desc=BY_MIN_DELEGATION, phase=self.phase)
                new_rewards.append(rl2)
                total_excluded_ratio += rl2.ratio
            else:
                new_rewards.append(rl2)

        total_service_fee_ratio = total_excluded_ratio

        # set fee rates and ratios
        for rl in self.filterskipped(new_rewards):
            rl.service_fee_rate = self.fee_calc.calculate(rl.originaladdress)
            rl.service_fee_ratio = rl.service_fee_rate * rl.ratio
            rl.ratio = rl.ratio - rl.service_fee_ratio
            rl.ratio3 = rl.ratio

            total_service_fee_ratio += rl.service_fee_ratio

        # create founders parent record
        if total_service_fee_ratio > ALMOST_ZERO:
            rl = RewardLog(
                address=TYPE_FOUNDERS_PARENT,
                type=TYPE_FOUNDERS_PARENT,
                staking_balance=0,
                current_balance=0,
            )
            rl.service_fee_rate = 0
            rl.service_fee_ratio = 0
            rl.ratio = total_service_fee_ratio
            rl.ratio3 = rl.ratio

            new_rewards.append(rl)

        return new_rewards, int(total_amount)
예제 #17
0
def main(args):
    logger.info(
        "Arguments Configuration = {}".format(json.dumps(args.__dict__, indent=1))
    )

    # Load payments file
    payments_file = os.path.expanduser(os.path.normpath(args.payments_file))
    if not os.path.isfile(payments_file):
        raise Exception("payments_file ({}) does not exist.".format(payments_file))

    with open(payments_file, "r") as file:
        payment_lines = file.readlines()

    payments_dict = {}
    for line in payment_lines:
        pkh, amt = line.split(":")
        pkh = pkh.strip()
        amt = float(amt.strip())

        payments_dict[pkh] = amt

    if not payments_dict:
        raise Exception("No payments to process")

    # Check if dry-run
    dry_run = args.dry_run

    # Get reporting directories
    reports_dir = os.path.expanduser(os.path.normpath(args.base_directory))

    # Check the disk size at the reports dir location
    if disk_is_full(reports_dir):
        raise Exception(
            "Disk is full at {}. Please free space to continue saving reports.".format(
                reports_dir
            )
        )

    # if in reports run mode, do not create consumers
    # create reports in reports directory
    if dry_run:
        reports_dir = os.path.join(reports_dir, SIMULATIONS_DIR, "")
    else:
        reports_dir = os.path.join(reports_dir, REPORTS_DIR, "")

    reports_dir = os.path.join(reports_dir, "manual", "")

    payments_root = get_payment_root(reports_dir, create=True)
    get_successful_payments_dir(payments_root, create=True)
    get_failed_payments_dir(payments_root, create=True)

    client_manager = ClientManager(
        node_endpoint=args.node_endpoint, signer_endpoint=args.signer_endpoint
    )

    for i in range(NB_CONSUMERS):
        c = PaymentConsumer(
            name="manual_payment_consumer",
            payments_dir=payments_root,
            key_name=args.paymentaddress,
            payments_queue=payments_queue,
            node_addr=args.node_endpoint,
            client_manager=client_manager,
            dry_run=dry_run,
            reactivate_zeroed=False,
            delegator_pays_ra_fee=False,
            delegator_pays_xfer_fee=False,
        )
        time.sleep(1)
        c.start()

    base_name_no_ext = os.path.basename(payments_file)
    base_name_no_ext = os.path.splitext(base_name_no_ext)[0]
    now = datetime.now()
    now_str = now.strftime("%Y%m%d%H%M%S")
    file_name = base_name_no_ext + "_" + now_str

    payment_items = []
    for key, value in payments_dict.items():
        pi = RewardLog.ExternalInstance(file_name, key, value)
        pi.payment = pi.payment * MUTEZ
        payment_items.append(pi)

        logger.info(
            "Reward created for cycle %s address %s amount %f fee %f tz type %s",
            pi.cycle,
            pi.address,
            pi.payment,
            pi.fee,
            pi.type,
        )

    payments_queue.put(PaymentBatch(None, 0, payment_items))
    payments_queue.put(PaymentBatch(None, 0, [RewardLog.ExitInstance()]))
예제 #18
0
def main(args):
    logger.info("Arguments Configuration = {}".format(
        json.dumps(args.__dict__, indent=1)))

    # 1- find where configuration is
    config_dir = os.path.expanduser(args.config_dir)

    # create configuration directory if it is not present
    # so that user can easily put his configuration there
    if config_dir and not os.path.exists(config_dir):
        os.makedirs(config_dir)

    # 3- load payments file
    payments_file = os.path.expanduser(args.payments_file)
    if not os.path.isfile(payments_file):
        raise Exception(
            "payments_file ({}) does not exist.".format(payments_file))

    with open(payments_file, 'r') as file:
        payment_lines = file.readlines()

    payments_dict = {}
    for line in payment_lines:
        pkh, amt = line.split(":")
        pkh = pkh.strip()
        amt = float(amt.strip())

        payments_dict[pkh] = amt

    if not payments_dict:
        raise Exception("No payments to process")

    # 6- is it a reports run
    dry_run = args.dry_run

    # 7- get reporting directories
    reports_dir = os.path.expanduser(args.reports_dir)
    # if in reports run mode, do not create consumers
    # create reports in reports directory
    if dry_run:
        reports_dir = os.path.expanduser("./reports")

    reports_dir = os.path.join(reports_dir, "manual")

    payments_root = get_payment_root(reports_dir, create=True)
    get_successful_payments_dir(payments_root, create=True)
    get_failed_payments_dir(payments_root, create=True)

    client_manager = ClientManager(node_endpoint=args.node_endpoint,
                                   signer_endpoint=args.signer_endpoint)

    for i in range(NB_CONSUMERS):
        c = PaymentConsumer(name='manual_payment_consumer',
                            payments_dir=payments_root,
                            key_name=args.paymentaddress,
                            payments_queue=payments_queue,
                            node_addr=args.node_endpoint,
                            client_manager=client_manager,
                            dry_run=dry_run,
                            reactivate_zeroed=False,
                            delegator_pays_ra_fee=False,
                            delegator_pays_xfer_fee=False)
        time.sleep(1)
        c.start()

    base_name_no_ext = os.path.basename(payments_file)
    base_name_no_ext = os.path.splitext(base_name_no_ext)[0]
    now = datetime.now()
    now_str = now.strftime("%Y%m%d%H%M%S")
    file_name = base_name_no_ext + "_" + now_str

    payment_items = []
    for key, value in payments_dict.items():
        pi = RewardLog.ExternalInstance(file_name, key, value)
        pi.payment = pi.payment * MUTEZ
        payment_items.append(pi)

        logger.info(
            "Reward created for cycle %s address %s amount %f fee %f tz type %s",
            pi.cycle, pi.address, pi.payment, pi.fee, pi.type)

    payments_queue.put(PaymentBatch(None, 0, payment_items))
    payments_queue.put(PaymentBatch(None, 0, [RewardLog.ExitInstance()]))
 def create_exit_payment():
     return RewardLog.ExitInstance()
    def test_merge(self):

        rewards = []

        #
        # Alice is a delegate, owner and founder
        rlAD = RewardLog(address="tz1Alice01", type="D", staking_balance=10000, current_balance=20000)
        rlAD.amount = 1234
        rewards.append(rlAD)

        rlAO = RewardLog(address="tz1Alice01", type="O", staking_balance=10000, current_balance=0)
        rlAO.amount = 2345
        rewards.append(rlAO)

        rlAF = RewardLog(address="tz1Alice01", type="F", staking_balance=10000, current_balance=0)
        rlAF.amount = 3456
        rewards.append(rlAF)

        #
        # Bob is only a delegate
        rlBD = RewardLog(address="tz1Bob01", type="D", staking_balance=10000, current_balance=0)
        rlBD.amount = 5000
        rewards.append(rlBD)

        #
        # Charlie is an Owner and Founder, not a delegate
        rlCO = RewardLog(address="tz1Charlie01", type="O", staking_balance=10000, current_balance=0)
        rlCO.amount = 1122
        rewards.append(rlCO)

        rlCF = RewardLog(address="tz1Charlie01", type="F", staking_balance=10000, current_balance=0)
        rlCF.amount = 2233
        rewards.append(rlCF)

        #
        # Merge Alice and Charlie's payouts
        mergedRewards = CalculatePhaseMerge().calculate(rewards)

        # Check that there now exists only 3 records. Alice's 3 should be merged to 1,
        # and Charlie's 2 merged to 1, Bob only had 1 to begin with
        self.assertEqual(3, len(mergedRewards))

        # Check that Alice's merged record equals the original 3
        aliceSum = 7035
        bobSum = 5000
        charlieSum = 3355

        for r in mergedRewards:
            if r.address == "tz1Alice01":
                self.assertEqual(r.amount, aliceSum)
                self.assertEqual(r.type, TYPE_MERGED)
            elif r.address == "tz1Bob01":
                self.assertEqual(r.amount, bobSum)
                self.assertEqual(r.type, TYPE_DELEGATOR)
            elif r.address == "tz1Charlie01":
                self.assertEqual(r.amount, charlieSum)
                self.assertEqual(r.type, TYPE_MERGED)
예제 #21
0
    def calculate(self, reward_data3, total_amount):

        new_rewards = []

        # move skipped records to next phase
        for rl3 in self.iterateskipped(reward_data3):
            new_rewards.append(rl3)

        for rl3 in self.filterskipped(reward_data3):
            if rl3.type == TYPE_FOUNDERS_PARENT:
                for addr, ratio in self.founders_map.items():
                    rl4 = RewardLog(addr, TYPE_FOUNDER, 0, 0)
                    # new ratio is parent ratio * ratio of the founder
                    rl4.ratio = ratio * rl3.ratio
                    rl4.ratio4 = rl4.ratio
                    rl4.service_fee_ratio = 0
                    rl4.service_fee_rate = 0
                    rl4.parent = rl3
                    new_rewards.append(rl4)

                # if no founders, add parent object to rewards list
                if not self.founders_map.items():
                    new_rewards.append(rl3)

            elif rl3.type == TYPE_OWNERS_PARENT:
                for addr, ratio in self.owners_map.items():
                    rl4 = RewardLog(addr, TYPE_OWNER,
                                    ratio * rl3.staking_balance, 0)
                    # new ratio is parent ratio * ratio of the owner
                    rl4.ratio = ratio * rl3.ratio
                    rl4.ratio4 = rl4.ratio
                    rl4.service_fee_ratio = 0
                    rl4.service_fee_rate = 0
                    rl4.parent = rl3
                    new_rewards.append(rl4)

                # if no owners, add parent object to rewards list
                if not self.owners_map.items():
                    new_rewards.append(rl3)
            else:
                rl3.ratio4 = rl3.ratio
                new_rewards.append(rl3)

        return new_rewards, total_amount
예제 #22
0
    def test_calculate_sepecials(self):
        rewards = []
        ratios = [0.25, 0.05, 0.3, 0.15, 0.25]
        total_reward = 1000

        for i, ratio in enumerate(ratios, start=1):
            rl0 = RewardLog(address="addr" + str(i),
                            type="D",
                            balance=total_reward * ratio)
            rl0.ratio = ratio
            rl0.ratio2 = ratio
            rewards.append(rl0)

        rewards.append(
            RewardLog("addrdummy", "D", 0).skip("skipped for testing", 2))

        excluded_set = {"addr1"}
        supporters_set = {"addr2"}
        specials_map = {"addr3": 30}

        fee_calculator = ServiceFeeCalculator(supporters_set, specials_map,
                                              20)  # 20% fee
        phase3 = CalculatePhase3(fee_calculator, excluded_set)

        new_rewards, new_total_reward = phase3.calculate(rewards, total_reward)

        # filter out skipped records
        new_rewards = list(rl for rl in new_rewards if not rl.skipped)

        # new_total_reward = total_reward
        self.assertEqual(total_reward, new_total_reward)

        # check new ratios sum up to 1
        # old and new reward amount is the same
        ratio_sum = 0.0
        service_fee_ratio_sum = 0.0

        founder_pl = None
        for rl3 in new_rewards:
            if rl3.skipped:
                continue

            if rl3.type == TYPE_FOUNDERS_PARENT:
                founder_pl = rl3

            ratio_sum += rl3.ratio3
            service_fee_ratio_sum += rl3.service_fee_ratio

        self.assertAlmostEqual(1.0, ratio_sum, delta=1e-6)
        self.assertAlmostEqual(0.17, service_fee_ratio_sum, delta=1e-6)
        self.assertAlmostEqual(0.42, founder_pl.ratio3, delta=1e-6)

        for rl3 in new_rewards:
            if rl3.skipped:
                continue

            if rl3.address == "addr2":
                self.assertEqual(0, rl3.service_fee_rate)
                self.assertEqual(0, rl3.service_fee_ratio)

            if rl3.address == "addr3":
                self.assertEqual(0.3, rl3.service_fee_rate)
                self.assertEqual(specials_map["addr3"] / 100 * rl3.ratio2,
                                 rl3.service_fee_ratio)
예제 #23
0
def main(args):
    logger.info("Arguments Configuration = {}".format(json.dumps(args.__dict__, indent=1)))

    # 1- find where configuration is
    config_dir = os.path.expanduser(args.config_dir)

    # create configuration directory if it is not present
    # so that user can easily put his configuration there
    if config_dir and not os.path.exists(config_dir):
        os.makedirs(config_dir)

    # 2- Load master configuration file if it is present
    master_config_file_path = os.path.join(config_dir, "master.yaml")

    master_cfg = {}
    if os.path.isfile(master_config_file_path):
        logger.info("Loading master configuration file {}".format(master_config_file_path))

        master_parser = YamlConfParser(ConfigParser.load_file(master_config_file_path))
        master_cfg = master_parser.parse()
    else:
        logger.info("master configuration file not present.")

    managers = None
    contracts_by_alias = None
    addresses_by_pkh = None
    if 'managers' in master_cfg:
        managers = master_cfg['managers']
    if 'contracts_by_alias' in master_cfg:
        contracts_by_alias = master_cfg['contracts_by_alias']
    if 'addresses_by_pkh' in master_cfg:
        addresses_by_pkh = master_cfg['addresses_by_pkh']

    # 3- load payments file
    payments_file = os.path.expanduser(args.payments_file)
    if not os.path.isfile(payments_file):
        raise Exception("payments_file ({}) does not exist.".format(payments_file))

    with open(payments_file, 'r') as file:
        payment_lines = file.readlines()

    payments_dict = {}
    for line in payment_lines:
        pkh, amt = line.split(":")
        pkh = pkh.strip()
        amt = float(amt.strip())

        payments_dict[pkh] = amt

    if not payments_dict:
        raise Exception("No payments to process")

    # 3- get client path

    client_path = get_client_path([x.strip() for x in args.executable_dirs.split(',')],
                                  args.docker, args.network,
                                  args.verbose)

    logger.debug("Dune client path is {}".format(client_path))

    # 4- get client path
    client_path = get_client_path([x.strip() for x in args.executable_dirs.split(',')],
                                  args.docker, args.network,
                                  args.verbose)

    logger.debug("Dune client path is {}".format(client_path))

    # 6- is it a reports run
    dry_run = args.dry_run

    # 7- get reporting directories
    reports_dir = os.path.expanduser(args.reports_dir)
    # if in reports run mode, do not create consumers
    # create reports in reports directory
    if dry_run:
        reports_dir = os.path.expanduser("./reports")

    reports_dir = os.path.join(reports_dir, "manual")

    payments_root = get_payment_root(reports_dir, create=True)
    get_successful_payments_dir(payments_root, create=True)
    get_failed_payments_dir(payments_root, create=True)

    wllt_clnt_mngr = WalletClientManager(client_path, contracts_by_alias, addresses_by_pkh, managers)

    for i in range(NB_CONSUMERS):
        c = PaymentConsumer(name='manual_payment_consumer', payments_dir=payments_root,
                            key_name=args.paymentaddress,
                            client_path=client_path, payments_queue=payments_queue, node_addr=args.node_addr,
                            wllt_clnt_mngr=wllt_clnt_mngr, verbose=args.verbose, dry_run=dry_run,
                            delegator_pays_xfer_fee=False)
        time.sleep(1)
        c.start()

    base_name_no_ext = os.path.basename(payments_file)
    base_name_no_ext = os.path.splitext(base_name_no_ext)[0]
    now = datetime.now()
    now_str = now.strftime("%Y%m%d%H%M%S")
    file_name = base_name_no_ext + "_" + now_str

    payment_items = []
    for key, value in payments_dict.items():
        pi = RewardLog.ExternalInstance(file_name, key, value)
        pi.payment = pi.payment * MUTEZ
        payment_items.append(pi)

        logger.info("Reward created for cycle %s address %s amount %f fee %f dn type %s",
                    pi.cycle, pi.address, pi.payment, pi.fee, pi.type)

    payments_queue.put(PaymentBatch(None, 0, payment_items))
    payments_queue.put(PaymentBatch(None, 0, [RewardLog.ExitInstance()]))