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

feat: inflating tail #6131

Closed
wants to merge 2 commits into from
Closed

feat: inflating tail #6131

wants to merge 2 commits into from

Conversation

CjS77
Copy link
Collaborator

@CjS77 CjS77 commented Feb 6, 2024

Summary

Adds a feature tari_feature_mainnet_emission to allow for tail emission
inflation. See #6122

This change necessitates the addition of 2 new consensus constants:
inflation_bips -- the annual inflation rate of the total supply.
and tail_emission_epoch_length, which controls the tail emission
inflation. These replace tail_emission.

We update the Protobuf definition for ConsensusConstants to account for
the new fields.

Getting Feature flags working

When formally implementing compiler features, the setting of the TARI_NETWORK
and (from now) TARI_TARGET_NETWORK envar and the related compiler flags matter.

These changes require that when tests run, the correct network flags are set.

For example, blocks::genesis_block::test::stagenet_genesis_sanity_check should
only run when TARI_NETWORK=stagenet.

While writing this PR, I uncovered a problem:
There is not a 1:1 mapping between the build target and the actual
network the binary may run on. E.g. the mainnet build can run on either
stagenet or mainnet.

Unfortunately the TARI_NETWORK envar was used to set both of these
variables. Without using feature flags, this discrepancy went unnoticed.
With feature flags, a lot of tests that implicitly assumed say a mainnet
target and a stagenet run would simply fail, with no way to resolve the
issue.

Since these are 2 different things, this commit introduced
TARI_TARGET_NETWORK which sets the build target. In most contexts,
this then decouples the configured network, which is specified by the
TARI_NETWORK envar as usual.

The other changes in this commit revolve around updating merkle roots
and the correct faucet sets to make the target/network/faucet
combination consistent.

CI workflows

The CI is configured to run tests for each of {target} ({network})

  • Testnet (Esme)
  • Nextnet (Nextnet)
  • Mainnet (Stagenet)

@CjS77 CjS77 requested a review from a team as a code owner February 6, 2024 11:03
@CjS77 CjS77 marked this pull request as draft February 6, 2024 11:03
@CjS77 CjS77 changed the title Inflating tail wip: inflating tail Feb 6, 2024
@ghpbot-tari-project ghpbot-tari-project added P-acks_required Process - Requires more ACKs or utACKs P-reviews_required Process - Requires a review from a lead maintainer to be merged labels Feb 6, 2024
Copy link

github-actions bot commented Feb 6, 2024

Test Results (CI)

    2 files     78 suites   29m 52s ⏱️
1 266 tests 1 265 ✅ 0 💤 1 ❌
2 524 runs  2 523 ✅ 0 💤 1 ❌

For more details on these failures, see this check.

Results for commit 7a6d6ac.

♻️ This comment has been updated with latest results.

Copy link

github-actions bot commented Feb 6, 2024

Test Results (Integration tests)

29 tests   29 ✅  11m 30s ⏱️
11 suites   0 💤
 2 files     0 ❌

Results for commit 7a6d6ac.

♻️ This comment has been updated with latest results.

@CjS77 CjS77 added A-base_node Area - The Tari base node executable and libraries W-consensus_breaking Warn - A change requiring a hard fork to be activated W-breaking A non-backward compatible change labels Feb 8, 2024
@CjS77 CjS77 marked this pull request as ready for review February 8, 2024 23:36
@CjS77 CjS77 requested a review from a team as a code owner February 8, 2024 23:36
@CjS77 CjS77 changed the title wip: inflating tail feat: inflating tail Feb 8, 2024
@CjS77 CjS77 force-pushed the inflating_tail branch 4 times, most recently from 938ab74 to 1f3b1b6 Compare February 9, 2024 01:06
Copy link
Collaborator

@SWvheerden SWvheerden left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not fan of adding this feature: tari_feature_mainnet_emission
It complicates the code and makes a lot of the code duplicate.
Why not let all run on the new tail emission ?

applications/minotari_merge_mining_proxy/build.rs Outdated Show resolved Hide resolved
build_features();
();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this correct?

applications/minotari_node/build.rs Outdated Show resolved Hide resolved
// to determine the correct inflation curve. So we need to include the premine in the emission curve.
let total_supply = self.rules.get_total_emission_at(height) +
if cfg!(tari_feature_mainnet_emission) {
MicroMinotari::from(0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this 0 does not seem correct.
Does mainnet emission not have a faucet value?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Read the comments

@CjS77
Copy link
Collaborator Author

CjS77 commented Feb 9, 2024

I am not fan of adding this feature: tari_feature_mainnet_emission It complicates the code and makes a lot of the code duplicate. Why not let all run on the new tail emission ?

If you read the PR description, I explain the need and rationale for testing the feature gate before mainnet. This is as good a test as any.

@ghpbot-tari-project ghpbot-tari-project added the CR-too_long Changes Requested - Your PR is too long label Feb 9, 2024
@@ -105,23 +105,23 @@ fn print_mr_values(block: &mut Block, print: bool) {

pub fn get_stagenet_genesis_block() -> ChainBlock {
let mut block = get_stagenet_genesis_block_raw();

eprintln!("Network: {:?}", Network::get_current_or_default());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missed?

This PR primarily adds tail emission inflation as a featuer; but it does
so using feature gates, which were broken in a few places, and so a big
part of this PR is resolving issues related to feature gates.

== Tail emission inflation

Adds a feature tari_feature_mainnet_emission to allow for tail emission
inflation. See #6122

This change necessitates the addition of 2 new consensus constants:
`inflation_bips` -- the annual inflation rate of the total supply.
and `tail_emission_epoch_length`, which controls the tail emission
inflation. These replace `tail_emission`.

We update the Protobuf definition for ConsensusConstants to account for
the new fields.

== Getting Feature flags working

When formally implementing compiler features, the setting of the `TARI_NETWORK`
and (from now) `TARI_TARGET_NETWORK` envar and the related compiler flags matter.

These changes require that when tests run, the correct network flags are set.

For example, blocks::genesis_block::test::stagenet_genesis_sanity_check should
only run when TARI_NETWORK=stagenet.

While writing this PR, I uncovered a problem:
There is not a 1:1 mapping between the build _target_ and the actual
network the binary may run on. E.g. the mainnet build can run on either
stagenet or mainnet.

Unfortunately the `TARI_NETWORK` envar was used to set both of these
variables. Without using feature flags, this discrepency went unnoticed.
With feature flags, a lot of tests that implicitly assumed say a mainnet
target and a stagenet run would simply fail, with no way to resolve the
issue.

Since these are 2 different things, this commit introduced
`TARI_TARGET_NETWORK` whicg sets the **build target**. In most contexts,
this then decouples the configured network, which is specified by the
`TARI_NETWORK` envar  as usual.

The other changes in this commit revolve around updating merkle roots
and the correct faucet sets to make the target/network/faucet
combination consistent.

== CI workflows

The CI is configured to run tests for each of
* Testnet (Esme)
* Nextnet (Nextnet)
* Mainnet (Mainnet, with some tests specifying stagenet)

=== remove env_logger

I used env_logger to try print the feature list at compiler time, but it
doesn't work, so rather remove it.

A better strategy (implemented in this commit) is to print
"tari_feature" as a prefix to the message emitted by build.rs. Then you
can do soemthing like

`cargo build -vv .... 2>/dev/null` | grep "tari_feature"`

Piping stderr to dev null hides all the noise from rustc, and then you
can grep for the messages you want (or omit the grep to see the usual
build messages among the rest)

===  set network according to pols

Sets the network according to the principle of least surprise. i.e. if
TARI_NETWORK is set, try and make that the default network.
Copy link
Contributor

@hansieodendaal hansieodendaal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can appreciate that a lot was accomplished in this PR.

However, I think it would be better to have a tail emission and then inflate the tail emission if inflating tail emission is required. When inflating tail emission is not desired that value can be zero in the consensus constants. This would make the code much simpler and more consistent and remove the requirement to have the tari_feature_mainnet_emission feature flag.

// Comment out the feature flag to run this test
#[test]
#[cfg(feature = "schedule_get_constants")]
fn esmeralda_schedule_get_constants() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this test removed? It should be added back in.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's covered by the new tail emission test. Esme's constants are changing with the tail inflation, so the test would fail anyway.

}

#[test]
fn esmeralda_schedule() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this test removed? It should be added back in.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same reason.

}

#[test]
fn nextnet_schedule() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this test removed? It should be added back in.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same reason

}

#[test]
fn stagenet_schedule() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this test removed? It should be added back in.

}

#[test]
fn igor_schedule() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this test removed?

pub(in crate::consensus) emission_tail: MicroMinotari,
/// The tail emission inflation rate in bips
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// The tail emission inflation rate in bips
/// The tail emission inflation rate in bips (basis points, otherwise known as bps or "bips")

@@ -167,6 +167,17 @@ jobs:
permissions:
checks: write
pull-requests: write
strategy:
matrix:
tari_target_network: [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a better name choice

Suggested change
tari_target_network: [
tari_network_map: [

Comment on lines +32 to +34
#[cfg(not(tari_feature_mainnet_emission))]
let (emission_initial, emission_decay, emission_tail) = cc.emission_amounts();
#[cfg(tari_feature_mainnet_emission)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why have this differentiation at all? It seems more prudent to choose if we will have inflating tail emission or not.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand the question.

If you're asking why inflating tail emission is using a feature gate, I gave a rationale in other comments.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why have both implementations in the code if we will only use one?

@@ -399,11 +393,13 @@ mod test {
}

#[test]
fn esmeralda_genesis_sanity_check() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This esemeralda genesis block sanity test should not be removed, it should be added back in. We need to do the genesis block sanity check for every network.

@CjS77
Copy link
Collaborator Author

CjS77 commented Feb 13, 2024

I can appreciate that a lot was accomplished in this PR.

However, I think it would be better to have a tail emission and then inflate the tail emission if inflating tail emission is required. When inflating tail emission is not desired that value can be zero in the consensus constants. This would make the code much simpler and more consistent and remove the requirement to have the tari_feature_mainnet_emission feature flag.

I'm happy to hear alternatives.

What you are suggesting is not 100% clear. Are you suggesting inflating tail emission via hardforks "as we go" every year?

If not, and you're proposing a transparent, code-based approach as presented here, then please offer an alternative. Note that your constraints are:

  • Inflation rate is not known a priori.
  • The inflation rate must be based on total supply, including faucets/premine
  • Tail emission must kick in the very block that the inflation rate falls below the target inflation rate.

@hansieodendaal
Copy link
Contributor

hansieodendaal commented Feb 13, 2024

What I mean is we can implement both schemes without feature flags and without duplicate code.

In the event that we want to have tail emission with tail inflation:

            emission_initial: INITIAL_EMISSION,
            emission_decay: &EMISSION_DECAY,
            emission_tail: 800 * T,
            inflation_bips: 1,
            tail_epoch_length: ANNUAL_BLOCKS,

In the event that we want to have tail inflation only:

            emission_initial: INITIAL_EMISSION,
            emission_decay: &EMISSION_DECAY,
            emission_tail: 0 * T,
            inflation_bips: 1,
            tail_epoch_length: ANNUAL_BLOCKS,

In the event that we want to have tail emission only:

            emission_initial: INITIAL_EMISSION,
            emission_decay: &EMISSION_DECAY,
            emission_tail: 800 * T,
            inflation_bips: 0,
            tail_epoch_length: 0,

In the event that we do not want either:

            emission_initial: INITIAL_EMISSION,
            emission_decay: &EMISSION_DECAY,
            emission_tail: 0 * T,
            inflation_bips: 0,
            tail_epoch_length: 0,

The fn next_reward function can change to this:

    fn next_reward(&mut self) {
        // Inflation phase
        if self.epoch > 0 && self.schedule.inflation_bips > 0 {
            self.epoch_counter += 1;
            if self.epoch_counter >= self.schedule.epoch_length {
                self.epoch_counter = 0;
                self.epoch += 1;
                self.reward = self.new_tail_emission();
            }
        } else {
            // Decay phase
            let cutoff = if self.schedule.tail > MicroMinotari::zero() {
                self.schedule.tail
            } else {
                self.new_tail_emission()
            };
            let next_decay_reward = self.next_decay_reward();
            if self.epoch == 0 && next_decay_reward > cutoff {
                self.reward = next_decay_reward;
            } else {
                self.epoch = 1;
                self.reward = cutoff;
            }
        }
    }

CjS77 added a commit that referenced this pull request Feb 21, 2024
Adds a feature `tari_feature_mainnet_emission` to allow for tail emission
inflation. See #6122

This change necessitates the addition of 2 new consensus constants:
`inflation_bips` -- the annual inflation rate of the total supply in
basis points (100 bips = 1 percentage point).
and `tail_emission_epoch_length`, which controls the tail emission
inflation.

These replace `tail_emission`.

We update the Protobuf definition for `ConsensusConstants` to account for
the new fields.

Updates tests

Adds `as_u128` to `MicroMinotari` since we need to perform a large
multiplication when calculating the inflation issuance.

Note: Replaces part of #6131
@CjS77 CjS77 mentioned this pull request Feb 21, 2024
4 tasks
@CjS77
Copy link
Collaborator Author

CjS77 commented Feb 21, 2024

Replaced by #6160 and #6162

@CjS77 CjS77 closed this Feb 21, 2024
@CjS77 CjS77 deleted the inflating_tail branch February 21, 2024 12:11
SWvheerden pushed a commit that referenced this pull request Feb 26, 2024
When formally implementing compiler features, the setting of the
`TARI_NETWORK` and (from now) `TARI_TARGET_NETWORK` envar and the
related compiler flags matter.

These changes require that when tests run, the correct network flags are
set.

For example,
`blocks::genesis_block::test::stagenet_genesis_sanity_check` should only
run when `TARI_NETWORK=stagenet`.

The current setup reveals a problem:
There is not a 1:1 mapping between the build _target_ and the actual
network the binary may run on. E.g. the mainnet build can run on either
stagenet or mainnet.

Unfortunately the `TARI_NETWORK` envar was used to set both of these
variables.

Since these are 2 different things, this commit introduced
`TARI_TARGET_NETWORK` which sets the **build target**. In most contexts,
this then decouples the configured network, which is specified by the
`TARI_NETWORK` envar as usual.

The other changes in this commit revolve around updating merkle roots
and the correct faucet sets to make the target/network/faucet
combination consistent.

The CI is configured to run tests for each of `{target} ({network})`
* Testnet (Esme)
* Nextnet (Nextnet)
* Mainnet (Stagenet)

Description
---

This replaces part of #6131 

Breaking Changes
---

- [x] None
- [ ] Requires data directory on base node to be deleted
- [ ] Requires hard fork
- [ ] Other - Please specify

<!-- Does this include a breaking change? If so, include this line as a
footer -->
<!-- BREAKING CHANGE: Description what the user should do, e.g. delete a
database, resync the chain -->
SWvheerden pushed a commit that referenced this pull request Feb 28, 2024
## Summary

Adds a feature `tari_feature_mainnet_emission` to allow for tail
emission
inflation. See #6122 

This change necessitates the addition of 2 new consensus constants:
`inflation_bips` -- the annual inflation rate of the total supply.
and `tail_emission_epoch_length`, which controls the tail emission
inflation. These replace `tail_emission`.

We update the Protobuf definition for `ConsensusConstants` to account
for
the new fields.

Note: Replaces part of #6131
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-base_node Area - The Tari base node executable and libraries CR-too_long Changes Requested - Your PR is too long P-acks_required Process - Requires more ACKs or utACKs P-reviews_required Process - Requires a review from a lead maintainer to be merged W-breaking A non-backward compatible change W-consensus_breaking Warn - A change requiring a hard fork to be activated
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants