Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pull-Based Periodic Budget Constrained Reward Payments #1305

Open
bedeho opened this issue Sep 11, 2020 · 1 comment
Open

Pull-Based Periodic Budget Constrained Reward Payments #1305

bedeho opened this issue Sep 11, 2020 · 1 comment
Labels

Comments

@bedeho
Copy link
Member

bedeho commented Sep 11, 2020

Background

A number of roles, such as council members and working group participants, all earn rewards periodically, and the spending to finance the reward comes out of a periodic budget that can be exhausted. Specifically, each participant earns a fixed number of tokens credited to a reward account at regular intervals. The problem with this is that the automatic payment, which is effectively a push-based mechanism, requires iteration over all actors, which further implies that the number must be capped at some safe upper bound. This may be satisfactory for these roles, but for example, paying out a possibly very large number of channel owners may not work. Moreover, the only remaining factor that constrains the number of workers in a working group is this payment methodology, hence having the option to drop that would also be interesting.

A natural way to work around this is to not have push payments but instead have pull-based cashouts.

Proposal

Here is a sketch, it appears to work and have no iteration over participants.

const BUDGET_PERIOD: u32;  

let recipients: Map<Id, Recipient>;

// Should be sum of `wage_per_block` of all `recipients
let totale_per_block_wage_burden;

// 
let total_owed_in_budget_period;

let budget: u32;

let nr_blocks_infeasible_payout; // since genesis, so its different

struct Recipient {
	pub nr_infeasible_payouts_before_last_cashout: u32,
	pub last_cashed_out_in_block: Option<u32>,
	pub wage_per_block: u32,
	pub destination: Account
}

pub fn on_block(block_height: u32) {

	if(block_height % BUDGET_PERIOD == 0) {

		total_owed_in_budget_period = 0;


	} else {

		total_owed_in_budget_period += totale_per_block_wage_burden;

		if (total_owed_in_budget_period > budget) {
			nr_blocks_infeasible_payout++;
		}

	}
}

pub fn add_recipient(id: Id, wage_per_block: u32) {

	recipients.insert(id, Recipient{
		nr_infeasible_payouts_before_last_cashout: 0,
		wage_per_block: wage_per_block
	})
}

pub fn cashout(recipient: & mut Recipient) {

	let nr_infeasible_payouts_after_last_cashout = nr_blocks_infeasible_payout - recipient.nr_infeasible_payouts_before_last_cashout;

	let now = current_block();

	let nr_blocks_after_last_cashout = now - last_cashed_out_in_block.ok_or(0);

	let nr_feasible_payouts_after_last_cashout = nr_blocks_after_last_cashout - nr_infeasible_payouts_after_last_cashout;

	let payable = nr_feasible_payouts_after_last_cashout*recipient.wage_per_block;

	CREDIT(recipient.destination, payable);

	// Update
	recipient.nr_infeasible_payouts_before_last_cashout += nr_infeasible_payouts_after_last_cashout;
	recipient.last_cashed_out_in_block = Some(now)
}

pub fn update_wage(recipient: & mut Recipient, new_wage_per_block: u32) {

	cashout(recipient);

	totale_per_block_wage_burden += -recipient.wage_per_block + new_wage_per_block;

	recipient.wage_per_block = new_wage_per_block;
}

pub fn update_budget(new_budget: u32) {
	budget = new_budget;
}

Questions

  1. Is this correct?
  2. Can it be further simplified?
  3. Is it too complex?

┆Issue is synchronized with this Asana task by Unito

@bedeho bedeho added the idea An idea for a new feature in any part of the Joystream label Sep 11, 2020
@bedeho
Copy link
Member Author

bedeho commented Sep 13, 2020

One obvious way to improve this has to be to take advantage of the fact that, if nothing changes, you know exactly at what block you will run out of funds, if at all, within the current budget. This should allow you to stop doing the recalculation on every block the way we are currently doing it.

@bedeho bedeho mentioned this issue Jan 22, 2021
@bedeho bedeho added runtime working-group-pallet Working group module and removed idea An idea for a new feature in any part of the Joystream labels Nov 27, 2021
@bedeho bedeho changed the title Idea: Pull-Based Periodic Budget Constrained Reward Payments Pull-Based Periodic Budget Constrained Reward Payments Nov 27, 2021
@bedeho bedeho added the mainnet label Dec 14, 2021
@bedeho bedeho mentioned this issue Apr 6, 2022
@bedeho bedeho added the urgent-post-mainnet Urgent post mainnet, do this frist! label Apr 29, 2022
@bedeho bedeho removed the mainnet label Apr 29, 2022
@kdembler kdembler removed the urgent-post-mainnet Urgent post mainnet, do this frist! label Apr 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants