From 858b5e4add36f28a59901fcbb05346434d68367f Mon Sep 17 00:00:00 2001 From: xm0onh Date: Tue, 7 May 2024 00:07:29 -0700 Subject: [PATCH] Add block reward address and conversion between space pledge and solution range --- docs/consensus/consensus_chain.md | 26 +++++++++++++++++++-- docs/consensus/proof_of_archival_storage.md | 21 +++++++++++++++-- docs/fees_and_rewards/Dynamic_Issuance.md | 4 ++-- docs/fees_and_rewards/Fees_and_Rewards.md | 8 +++---- 4 files changed, 49 insertions(+), 10 deletions(-) diff --git a/docs/consensus/consensus_chain.md b/docs/consensus/consensus_chain.md index 6dcf245..6c659b3 100644 --- a/docs/consensus/consensus_chain.md +++ b/docs/consensus/consensus_chain.md @@ -9,8 +9,8 @@ keywords: - transaction - synchronization last_update: - date: 02/14/2024 - author: Dariia Porechna + date: 05/07/2024 + author: Saeid Yazdinejad --- Unless specified otherwise below, consensus chain primitives are inherited from Substrate. @@ -125,3 +125,25 @@ Justifications contain a set of all PoT checkpoints since the parent block up to 3. Import and verify blocks. Ban bad peers. 4. When you are close to tip (~18 blocks) switch to keep-up sync 5. When get to tip start participate in consensus + +## Block Reward Address +In the current blockchain farming setup, a farmer’s identity is used for plot creation, block signing, and receiving block rewards, posing risks like plot invalidation on testnet when used across multiple nodes and incompatibility with cold wallets. To address these, it's proposed to decouple the farmer's identity from the reward address by introducing a `--reward-address` argument in the farmer app, allowing the specification of a separate address for block rewards. This change, reflected in the updated `Solution` structure with an additional `reward_address` field, would enhance security, support multi-replica farming, and align farming operations with practices in PoW mining where reward addresses are independent of operational identities. + +```rust +pub struct Solution { + /// Public key of the farmer that created the solution + pub public_key: AccountId, ++ /// Address for receiving block reward ++ pub reward_address: AccountId, + /// Index of encoded piece + pub piece_index: u64, + /// Encoding + pub encoding: Piece, + /// Signature of the tag + pub signature: Signature, + /// Local challenge derived from global challenge using farmer's identity. + pub local_challenge: LocalChallenge, + /// Tag (hmac of encoding and salt) + pub tag: Tag, +} +``` diff --git a/docs/consensus/proof_of_archival_storage.md b/docs/consensus/proof_of_archival_storage.md index 5406aa0..ee121ec 100644 --- a/docs/consensus/proof_of_archival_storage.md +++ b/docs/consensus/proof_of_archival_storage.md @@ -8,7 +8,7 @@ keywords: - plotting - auditing last_update: - date: 03/12/2024 + date: 05/07/2024 author: Saeid Yazdinejad --- import Collapsible from '@site/src/components/Collapsible/Collapsible'; @@ -133,7 +133,7 @@ This extra data is added to the end of the [SCALE-encoded](https://docs.substrat 1. Given the total allocated disk space, reserve some space ($<2\%$) for commitments and other auxiliary information. 2. Create a single plot of `plot_size = allocated_plotting_space`. Sizes of farmer plots are independent from size of blockchain history, but must be a multiple of `sector_size`. -3. Generate a farmer identity, that is a key pair `public_key, secret_key` under the digital signature scheme. These signing keys are independent from reward address of an entity (exactly as payout address in Bitcoin mining) described in [Block reward address](https://www.notion.so/Block-reward-address-5cd4467a70974f94b7d4dcdb44c6e068?pvs=21). +3. Generate a farmer identity, that is a key pair `public_key, secret_key` under the digital signature scheme. These signing keys are independent from reward address of an entity (exactly as payout address in Bitcoin mining) described in [Block reward address](docs/consensus/consensus_chain.md#block-reward-address). 4. Derive an identifier `public_key_hash` as `hash(public_key)`. This farmer id will also serve as the basis for their single global network peer id in the DHT. 5. Determine the `sector_count = plot_size / sector_size`. 6. **Verifiable Sector Construction (VSC)**: @@ -379,3 +379,20 @@ Global `solution_range` is adjusted every era accordingly to actual and expected 2. At the start of a new era, compute and store new `solution_range` $\text{next\_solution\_range} = \max\left(\min\left(\frac{\text{era\_slot\_count}}{\text{ERA\_DURATION\_IN\_BLOCKS}}*\text{SLOT\_PROBABILITY}, 4\right), 1/4\right)*\text{solution\_range}$. + +### Conversion Rate Between Solution Range and Space Pledged + +The relationship between the solution range and the amount of space pledged is dynamically calculated using the function `solution_range_to_sectors`. This function computes the number of sectors corresponding to a given solution range by adjusting for slot probability and the configuration of data within sectors. Specifically, the maximum possible solution range (`SolutionRange::MAX`) is first reduced according to the slot probability, which reflects the desired frequency of successful block production. This is further adjusted by the distribution of data, particularly the ratio of the number of chunks per s-bucket in each sector (`MAX_PIECES_IN_SECTOR * Record::NUM_CHUNKS / Record::NUM_S_BUCKETS`), to account for the probability of an occupied s-bucket being successfully audited in the verification process. The resulting figure is then divided by the current solution range to determine the total number of sectors that this solution range can effectively cover. + +```rust +const fn solution_range_to_sectors(solution_range: SolutionRange) -> u64 { + let sectors = SolutionRange::MAX + // Account for slot probability + / SLOT_PROBABILITY.1 * SLOT_PROBABILITY.0 + // Now take sector size and probability of hitting occupied s-bucket in sector into account + / (MAX_PIECES_IN_SECTOR as u64 * Record::NUM_CHUNKS as u64 / Record::NUM_S_BUCKETS as u64); + + // Take solution range into account + sectors / solution_range +} +``` diff --git a/docs/fees_and_rewards/Dynamic_Issuance.md b/docs/fees_and_rewards/Dynamic_Issuance.md index 9eee8db..68c6430 100644 --- a/docs/fees_and_rewards/Dynamic_Issuance.md +++ b/docs/fees_and_rewards/Dynamic_Issuance.md @@ -7,7 +7,7 @@ keywords: - rewards - WIP last_update: - date: 04/23/2024 + date: 05/07/2024 author: Saeid Yazdinejad --- import Collapsible from '@site/src/components/Collapsible/Collapsible'; @@ -23,7 +23,7 @@ TLDR: The farmer who proposed a block gets some fresh SSC + fees, and voters get The rewards issuance is not enabled by default at the chain genesis. After the genesis block, several things need to happen before authoring blocks by anyone, and rewards can be enabled (See [genesis](https://subnomicon.subspace.network/docs/consensus/genesis) algorithm). Then: -1. Define a target space pledged to the network at which the rewards will be enabled (i.e., 8PiB for Gemini-3h). In the runtime, it is defined in terms of the target value of the solution range [`solution_range_for_rewards - TODO`](https://github.com/subspace/protocol-specs/issues/13). +1. Define a target space pledged to the network at which the rewards will be enabled (i.e., 8PiB for Gemini-3h). In the runtime, it is defined in terms of the target value of the solution range [`solution_range_for_rewards`](docs/consensus/proof_of_archival_storage.md#conversion-rate-between-solution-range-and-space-pledged). 2. Identify an assumed current space pledged `initial_solution_range`. 3. Enable solution range adjustment starting at `initial_solution_range` at the next era 4. Set in the runtime the `solution_range_for_rewards` below which to automatically enable rewards. diff --git a/docs/fees_and_rewards/Fees_and_Rewards.md b/docs/fees_and_rewards/Fees_and_Rewards.md index c12f384..15a2813 100644 --- a/docs/fees_and_rewards/Fees_and_Rewards.md +++ b/docs/fees_and_rewards/Fees_and_Rewards.md @@ -7,7 +7,7 @@ keywords: - rewards - WIP last_update: - date: 04/17/2024 + date: 05/07/2024 author: Saeid Yazdinejad --- import Collapsible from '@site/src/components/Collapsible/Collapsible'; @@ -99,7 +99,7 @@ As opposed to having a fixed issuance rate, the Subspace Network implements a dy TLDR: The farmer who proposed a block gets some fresh SSC + fees, and voters get some fresh SSC regardless of what the proposer got. -[Dynamic Issuance Specification](../../docs/fees_and_rewards/Dynamic_Issuance) +[Dynamic Issuance Specification](docs/fees_and_rewards/Dynamic_Issuance.md) ## Consensus Extrinsic Fees @@ -199,14 +199,14 @@ The user is charged when the domain block that includes the bundle is executed. **How** -The `ER::block_fees` field stores the fees split by storage and compute fees (similar to how the consensus chain stores block fees). The fraud proof for this field ([**Invalid Block Fees** ](../../docs/decex/fraud_proofs#invalid-block-fees)) handles both parts. The [**Inherent Extrinsic**](../../docs/decex/fraud_proofs#inherent-extrinsic) fraud proof variant handles the invalid inherent proof for `transaction_byte_fee`. +The `ER::block_fees` field stores the fees split by storage and compute fees (similar to how the consensus chain stores block fees). The fraud proof for this field ([**Invalid Block Fees** ](docs/decex/fraud_proofs.md#invalid-block-fees)) handles both parts. The [**Inherent Extrinsic**](docs/decex/fraud_proofs.md#inherent-extrinsic) fraud proof variant handles the invalid inherent proof for `transaction_byte_fee`. When registering onto a domain, a percentage $s$ (currently 20%) of the operator’s stake is transferred to a “storage fee fund”. A `storage_fund_account` is a separate account from stake, derived uniquely from operator public key. The storage fee for a bundle $B$ will be paid from this account. We can estimate the minimum operator stake required to be able to produce bundles for a challenge period. Any subsequent operator&nominator stake deposits will automatically allocate the same percentage $s$ to the `storage_fund_account`. Unlike staking deposits that are locked in the nominator account in `pallet_balances`, a % required for storage fees is transferred to `storage_fund_account` sub-account for this operator. -Every nomination deposit gives the same $s$ % to storage fees reserve like the operator deposit. Storage fees are shared with nominators according to their shares in the pool for withdrawals, however, the amount of `storage_fund_account` and current epoch storage fees do not influence the share value (to sustain our current [assumption](https://www.notion.so/3fb0ec6e4d204c4881a7df50ef58da8f?pvs=21) of increasing share value). +Every nomination deposit gives the same $s$ % to storage fees reserve like the operator deposit. Storage fees are shared with nominators according to their shares in the pool for withdrawals, however, the amount of `storage_fund_account` and current epoch storage fees do not influence the share value. Withdrawal amounts are converted to shares according to end of epoch share value and the same amount of shares is withdrawn from `storage_fund_account`. See [example](#deposit--withdraw-example). If the `storage_fund_account` does not have enough funds to pay the consensus chain for blockspace, the operator cannot submit a new bundle (or only include as many tx as they can pay for). They can either top it up via a deposit or wait until some of the rewards clear the challenge period (both take effect at the end of epoch).