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

[ARC-0042] Adjust reward algorithms to utilize timestamps #2569

Merged
merged 9 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions console/network/src/canary_v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,13 @@ impl Network for CanaryV0 {
/// The transmission checksum type.
type TransmissionChecksum = u128;

/// The block height from which consensus V2 rules apply.
#[cfg(not(any(test, feature = "test")))]
const CONSENSUS_V2_HEIGHT: u32 = 2_500_000;
// TODO (raychu86): Update this value based on the desired canary height.
/// The block height from which consensus V2 rules apply.
#[cfg(any(test, feature = "test"))]
const CONSENSUS_V2_HEIGHT: u32 = 0;
/// The network edition.
const EDITION: u16 = 0;
/// The genesis block coinbase target.
Expand Down
3 changes: 3 additions & 0 deletions console/network/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ pub trait Network:
/// The network edition.
const EDITION: u16;

/// The block height from which consensus V2 rules apply.
const CONSENSUS_V2_HEIGHT: u32;

/// The function name for the inclusion circuit.
const INCLUSION_FUNCTION_NAME: &'static str;

Expand Down
7 changes: 7 additions & 0 deletions console/network/src/mainnet_v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,13 @@ impl Network for MainnetV0 {
/// The transmission checksum type.
type TransmissionChecksum = u128;

/// The block height from which consensus V2 rules apply.
#[cfg(not(any(test, feature = "test")))]
const CONSENSUS_V2_HEIGHT: u32 = 2_000_000;
// TODO (raychu86): Update this value based on the desired mainnet height.
/// The block height from which consensus V2 rules apply.
#[cfg(any(test, feature = "test"))]
const CONSENSUS_V2_HEIGHT: u32 = 0;
/// The network edition.
const EDITION: u16 = 0;
/// The genesis block coinbase target.
Expand Down
7 changes: 7 additions & 0 deletions console/network/src/testnet_v0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,13 @@ impl Network for TestnetV0 {
/// The transmission checksum type.
type TransmissionChecksum = u128;

/// The block height from which consensus V2 rules apply.
#[cfg(not(any(test, feature = "test")))]
const CONSENSUS_V2_HEIGHT: u32 = 2_500_000;
// TODO (raychu86): Update this value based on the desired testnet height.
/// The block height from which consensus V2 rules apply.
#[cfg(any(test, feature = "test"))]
const CONSENSUS_V2_HEIGHT: u32 = 10;
/// The network edition.
const EDITION: u16 = 0;
/// The genesis block coinbase target.
Expand Down
842 changes: 813 additions & 29 deletions ledger/block/src/helpers/target.rs

Large diffs are not rendered by default.

17 changes: 14 additions & 3 deletions ledger/block/src/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,9 +388,12 @@ impl<N: Network> Block<N> {
)?;

// Calculate the expected coinbase reward.
let expected_coinbase_reward = coinbase_reward(
let expected_coinbase_reward = coinbase_reward::<N>(
raychu86 marked this conversation as resolved.
Show resolved Hide resolved
height,
timestamp,
N::GENESIS_TIMESTAMP,
N::STARTING_SUPPLY,
N::ANCHOR_TIME,
N::ANCHOR_HEIGHT,
N::BLOCK_TIME,
combined_proof_target,
Expand All @@ -402,9 +405,17 @@ impl<N: Network> Block<N> {
let expected_transaction_fees =
self.transactions.iter().map(|tx| Ok(*tx.priority_fee_amount()?)).sum::<Result<u64>>()?;

// Calculate the time since last block.
let time_since_last_block = timestamp.saturating_sub(previous_block.timestamp());
// Compute the expected block reward.
let expected_block_reward =
block_reward(N::STARTING_SUPPLY, N::BLOCK_TIME, expected_coinbase_reward, expected_transaction_fees);
let expected_block_reward = block_reward::<N>(
raychu86 marked this conversation as resolved.
Show resolved Hide resolved
height,
N::STARTING_SUPPLY,
N::BLOCK_TIME,
time_since_last_block,
expected_coinbase_reward,
expected_transaction_fees,
);
// Compute the expected puzzle reward.
let expected_puzzle_reward = puzzle_reward(expected_coinbase_reward);

Expand Down
6 changes: 5 additions & 1 deletion ledger/src/advance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,9 +295,12 @@ impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
)?;

// Calculate the coinbase reward.
let coinbase_reward = coinbase_reward(
let coinbase_reward = coinbase_reward::<N>(
next_height,
next_timestamp,
N::GENESIS_TIMESTAMP,
N::STARTING_SUPPLY,
N::ANCHOR_TIME,
N::ANCHOR_HEIGHT,
N::BLOCK_TIME,
combined_proof_target,
Expand All @@ -316,6 +319,7 @@ impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
// Speculate over the ratifications, solutions, and transactions.
let (ratifications, transactions, aborted_transaction_ids, ratified_finalize_operations) = self.vm.speculate(
state,
next_timestamp.saturating_sub(previous_block.timestamp()),
Some(coinbase_reward),
candidate_ratifications,
&solutions,
Expand Down
11 changes: 9 additions & 2 deletions ledger/src/check_next_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,15 @@ impl<N: Network, C: ConsensusStorage<N>> Ledger<N, C> {
)?;

// Ensure speculation over the unconfirmed transactions is correct and ensure each transaction is well-formed and unique.
let ratified_finalize_operations =
self.vm.check_speculate(state, block.ratifications(), block.solutions(), block.transactions(), rng)?;
let time_since_last_block = block.timestamp().saturating_sub(self.latest_timestamp());
let ratified_finalize_operations = self.vm.check_speculate(
state,
time_since_last_block,
block.ratifications(),
block.solutions(),
block.transactions(),
rng,
)?;

// Retrieve the committee lookback.
let committee_lookback = {
Expand Down
102 changes: 87 additions & 15 deletions synthesizer/src/vm/finalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ impl<N: Network, C: ConsensusStorage<N>> VM<N, C> {
/// `Ratify::BlockReward(block_reward)` and `Ratify::PuzzleReward(puzzle_reward)`
/// to the front of the `ratifications` list.
#[inline]
#[allow(clippy::too_many_arguments)]
pub fn speculate<'a, R: Rng + CryptoRng>(
&self,
state: FinalizeGlobalState,
time_since_last_block: i64, // TODO (raychu86): Consider moving this value into `FinalizeGlobalState`.
raychu86 marked this conversation as resolved.
Show resolved Hide resolved
coinbase_reward: Option<u64>,
candidate_ratifications: Vec<Ratify<N>>,
candidate_solutions: &Solutions<N>,
Expand Down Expand Up @@ -62,6 +64,7 @@ impl<N: Network, C: ConsensusStorage<N>> VM<N, C> {
let (ratifications, confirmed_transactions, speculation_aborted_transactions, ratified_finalize_operations) =
self.atomic_speculate(
state,
time_since_last_block,
coinbase_reward,
candidate_ratifications,
candidate_solutions,
Expand Down Expand Up @@ -104,6 +107,7 @@ impl<N: Network, C: ConsensusStorage<N>> VM<N, C> {
pub fn check_speculate<R: Rng + CryptoRng>(
&self,
state: FinalizeGlobalState,
time_since_last_block: i64,
ratifications: &Ratifications<N>,
solutions: &Solutions<N>,
transactions: &Transactions<N>,
Expand All @@ -129,7 +133,14 @@ impl<N: Network, C: ConsensusStorage<N>> VM<N, C> {

// Performs a **dry-run** over the list of ratifications, solutions, and transactions.
let (speculate_ratifications, confirmed_transactions, aborted_transactions, ratified_finalize_operations) =
self.atomic_speculate(state, None, candidate_ratifications, solutions, candidate_transactions.iter())?;
self.atomic_speculate(
state,
time_since_last_block,
None,
candidate_ratifications,
solutions,
candidate_transactions.iter(),
)?;

// Ensure the ratifications after speculation match.
if ratifications != &speculate_ratifications {
Expand Down Expand Up @@ -193,6 +204,7 @@ impl<N: Network, C: ConsensusStorage<N>> VM<N, C> {
fn atomic_speculate<'a>(
&self,
state: FinalizeGlobalState,
time_since_last_block: i64,
coinbase_reward: Option<u64>,
ratifications: Vec<Ratify<N>>,
solutions: &Solutions<N>,
Expand Down Expand Up @@ -478,9 +490,11 @@ impl<N: Network, C: ConsensusStorage<N>> VM<N, C> {
};

// Compute the block reward.
let block_reward = ledger_block::block_reward(
let block_reward = ledger_block::block_reward::<N>(
state.block_height(),
N::STARTING_SUPPLY,
N::BLOCK_TIME,
time_since_last_block,
coinbase_reward,
transaction_fees,
);
Expand Down Expand Up @@ -1458,8 +1472,10 @@ finalize transfer_public:
rng: &mut R,
) -> Result<Block<CurrentNetwork>> {
// Speculate on the candidate ratifications, solutions, and transactions.
let time_since_last_block = CurrentNetwork::BLOCK_TIME as i64;
let (ratifications, transactions, aborted_transaction_ids, ratified_finalize_operations) = vm.speculate(
sample_finalize_state(previous_block.height() + 1),
time_since_last_block,
None,
vec![],
&None.into(),
Expand All @@ -1478,7 +1494,7 @@ finalize transfer_public:
CurrentNetwork::GENESIS_PROOF_TARGET,
previous_block.last_coinbase_target(),
previous_block.last_coinbase_timestamp(),
CurrentNetwork::GENESIS_TIMESTAMP + 1,
previous_block.timestamp().saturating_add(time_since_last_block),
)?;

// Construct the new block header.
Expand Down Expand Up @@ -1736,6 +1752,7 @@ finalize transfer_public:
let (ratifications, confirmed_transactions, aborted_transaction_ids, _) = vm
.speculate(
sample_finalize_state(1),
CurrentNetwork::BLOCK_TIME as i64,
None,
vec![],
&None.into(),
Expand Down Expand Up @@ -1763,7 +1780,14 @@ finalize transfer_public:

// Ensure the dry run of the redeployment will cause a reject transaction to be created.
let (_, candidate_transactions, aborted_transaction_ids, _) = vm
.atomic_speculate(sample_finalize_state(1), None, vec![], &None.into(), [deployment_transaction].iter())
.atomic_speculate(
sample_finalize_state(1),
CurrentNetwork::BLOCK_TIME as i64,
None,
vec![],
&None.into(),
[deployment_transaction].iter(),
)
.unwrap();
assert_eq!(candidate_transactions.len(), 1);
assert!(matches!(candidate_transactions[0], ConfirmedTransaction::RejectedDeploy(..)));
Expand Down Expand Up @@ -1849,8 +1873,16 @@ finalize transfer_public:

// Speculate on the transactions.
let transactions = [bond_validator_transaction.clone()];
let (_, confirmed_transactions, _, _) =
vm.atomic_speculate(sample_finalize_state(1), None, vec![], &None.into(), transactions.iter()).unwrap();
let (_, confirmed_transactions, _, _) = vm
.atomic_speculate(
sample_finalize_state(1),
CurrentNetwork::BLOCK_TIME as i64,
None,
vec![],
&None.into(),
transactions.iter(),
)
.unwrap();

// Assert that the transaction is rejected.
assert_eq!(confirmed_transactions.len(), 1);
Expand Down Expand Up @@ -1952,8 +1984,16 @@ finalize transfer_public:
// Transfer_20 -> Balance = 20 - 20 = 0
{
let transactions = [mint_10.clone(), transfer_10.clone(), transfer_20.clone()];
let (_, confirmed_transactions, aborted_transaction_ids, _) =
vm.atomic_speculate(sample_finalize_state(1), None, vec![], &None.into(), transactions.iter()).unwrap();
let (_, confirmed_transactions, aborted_transaction_ids, _) = vm
.atomic_speculate(
sample_finalize_state(1),
CurrentNetwork::BLOCK_TIME as i64,
None,
vec![],
&None.into(),
transactions.iter(),
)
.unwrap();

// Assert that all the transactions are accepted.
assert_eq!(confirmed_transactions.len(), 3);
Expand All @@ -1972,8 +2012,16 @@ finalize transfer_public:
// Transfer_30 -> Balance = 30 - 30 = 0
{
let transactions = [transfer_20.clone(), mint_10.clone(), mint_20.clone(), transfer_30.clone()];
let (_, confirmed_transactions, aborted_transaction_ids, _) =
vm.atomic_speculate(sample_finalize_state(1), None, vec![], &None.into(), transactions.iter()).unwrap();
let (_, confirmed_transactions, aborted_transaction_ids, _) = vm
.atomic_speculate(
sample_finalize_state(1),
CurrentNetwork::BLOCK_TIME as i64,
None,
vec![],
&None.into(),
transactions.iter(),
)
.unwrap();

// Assert that all the transactions are accepted.
assert_eq!(confirmed_transactions.len(), 4);
Expand All @@ -1992,8 +2040,16 @@ finalize transfer_public:
// Transfer_10 -> Balance = 0 - 10 = -10 (should be rejected)
{
let transactions = [transfer_20.clone(), transfer_10.clone()];
let (_, confirmed_transactions, aborted_transaction_ids, _) =
vm.atomic_speculate(sample_finalize_state(1), None, vec![], &None.into(), transactions.iter()).unwrap();
let (_, confirmed_transactions, aborted_transaction_ids, _) = vm
.atomic_speculate(
sample_finalize_state(1),
CurrentNetwork::BLOCK_TIME as i64,
None,
vec![],
&None.into(),
transactions.iter(),
)
.unwrap();

// Assert that the accepted and rejected transactions are correct.
assert_eq!(confirmed_transactions.len(), 2);
Expand All @@ -2016,8 +2072,16 @@ finalize transfer_public:
// Transfer_10 -> Balance = 10 - 10 = 0
{
let transactions = [mint_20.clone(), transfer_30.clone(), transfer_20.clone(), transfer_10.clone()];
let (_, confirmed_transactions, aborted_transaction_ids, _) =
vm.atomic_speculate(sample_finalize_state(1), None, vec![], &None.into(), transactions.iter()).unwrap();
let (_, confirmed_transactions, aborted_transaction_ids, _) = vm
.atomic_speculate(
sample_finalize_state(1),
CurrentNetwork::BLOCK_TIME as i64,
None,
vec![],
&None.into(),
transactions.iter(),
)
.unwrap();

// Assert that the accepted and rejected transactions are correct.
assert_eq!(confirmed_transactions.len(), 4);
Expand Down Expand Up @@ -2116,7 +2180,15 @@ function ped_hash:

// Speculatively execute the transaction. Ensure that this call does not panic and returns a rejected transaction.
let (_, confirmed_transactions, aborted_transaction_ids, _) = vm
.speculate(sample_finalize_state(1), None, vec![], &None.into(), [transaction.clone()].iter(), rng)
.speculate(
sample_finalize_state(1),
CurrentNetwork::BLOCK_TIME as i64,
None,
vec![],
&None.into(),
[transaction.clone()].iter(),
rng,
)
.unwrap();
assert!(aborted_transaction_ids.is_empty());

Expand Down
16 changes: 12 additions & 4 deletions synthesizer/src/vm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ impl<N: Network, C: ConsensusStorage<N>> VM<N, C> {
let state = FinalizeGlobalState::new_genesis::<N>()?;
// Speculate on the ratifications, solutions, and transactions.
let (ratifications, transactions, aborted_transaction_ids, ratified_finalize_operations) =
self.speculate(state, None, ratifications, &solutions, transactions.iter(), rng)?;
self.speculate(state, 0, None, ratifications, &solutions, transactions.iter(), rng)?;
ensure!(
aborted_transaction_ids.is_empty(),
"Failed to initialize a genesis block - found aborted transaction IDs"
Expand Down Expand Up @@ -764,8 +764,16 @@ function compute:
let previous_block = vm.block_store().get_block(&block_hash).unwrap().unwrap();

// Construct the new block header.
let (ratifications, transactions, aborted_transaction_ids, ratified_finalize_operations) =
vm.speculate(sample_finalize_state(1), None, vec![], &None.into(), transactions.iter(), rng)?;
let time_since_last_block = MainnetV0::BLOCK_TIME as i64;
let (ratifications, transactions, aborted_transaction_ids, ratified_finalize_operations) = vm.speculate(
sample_finalize_state(1),
time_since_last_block,
None,
vec![],
&None.into(),
transactions.iter(),
rng,
)?;

// Construct the metadata associated with the block.
let metadata = Metadata::new(
Expand All @@ -778,7 +786,7 @@ function compute:
MainnetV0::GENESIS_PROOF_TARGET,
previous_block.last_coinbase_target(),
previous_block.last_coinbase_timestamp(),
MainnetV0::GENESIS_TIMESTAMP + 1,
previous_block.timestamp().saturating_add(time_since_last_block),
)?;

let header = Header::from(
Expand Down
Loading