Compare commits

...

31 Commits

Author SHA1 Message Date
Jimmy Debe
eb27ea421a Update linting 2025-12-04 23:11:45 -05:00
Jimmy Debe
9933b7ca74 Merge branch 'main' into vac-Staking1 2025-09-08 20:02:48 -04:00
Jimmy Debe
3505da6bd6 sds lint fix (#177)
Fix lint issue in sds.md
2025-08-22 14:53:34 +02:00
seugu
3b968ccce3 VAC/RAW/ ETH-MLS-OFFCHAIN RFC (#166)
The first version of decentralized MLS (de-MLS) aka ETH-MLS-OFFCHAIN
RFC.

---------

Co-authored-by: Ekaterina Broslavskaya <seemenkina@gmail.com>
Co-authored-by: Jimmy Debe <91767824+jimstir@users.noreply.github.com>
Co-authored-by: kaiserd <1684595+kaiserd@users.noreply.github.com>
2025-08-21 13:33:59 +03:00
Hanno Cornelius
536d31b5b7 docs: re-add sender ID to messages (#170)
Re-added the concept of a participant ID and the corresponding
`sender_id` field in each SDS message.

This is useful to filter "self-triggered" messages as described in
https://github.com/waku-org/js-waku/pull/2528

However, this will also be a necessary part of the protocol once p2p
message exchange is added.

---------

Co-authored-by: fryorcraken <110212804+fryorcraken@users.noreply.github.com>
Co-authored-by: shash256 <111925100+shash256@users.noreply.github.com>
2025-08-19 16:38:42 +01:00
fryorcraken
4361e2958f Add implementation recommendation for metadata (#168)
Based on recent learnings.

---------

Co-authored-by: Hanno Cornelius <68783915+jm-clius@users.noreply.github.com>
2025-07-31 12:51:04 +10:00
Jimmy Debe
88e326289a Update staking-streamer.md 2025-07-03 05:56:59 -04:00
Jimmy Debe
78323d890a Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-07-02 07:57:39 -04:00
Jimmy Debe
24fe617c5f Update staking-streamer.md 2025-07-02 07:57:15 -04:00
Jimmy Debe
502d598be3 Update staking-streamer.md 2025-07-01 06:30:29 -04:00
Jimmy Debe
f44fc6eb93 Update staking-streamer.md 2025-06-30 07:38:54 -04:00
Jimmy Debe
36439eb400 Update staking-streamer.md 2025-06-30 07:16:37 -04:00
Jimmy Debe
1258e483fe Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 07:06:59 -04:00
Jimmy Debe
882177064b Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 07:06:38 -04:00
Jimmy Debe
4708ef71f3 Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 07:06:07 -04:00
Jimmy Debe
4b333dae16 Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 07:05:24 -04:00
Jimmy Debe
b768883f95 Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 07:05:15 -04:00
Jimmy Debe
624cc8370b Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 07:05:05 -04:00
Jimmy Debe
966b31d95e Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 07:04:56 -04:00
Jimmy Debe
78be8ca331 Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 07:04:45 -04:00
Jimmy Debe
860ffe6b11 Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 07:04:31 -04:00
Jimmy Debe
dac06391c5 Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 07:02:03 -04:00
Jimmy Debe
11258ec0b6 Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 06:58:58 -04:00
Jimmy Debe
f31f41fec9 Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 06:58:41 -04:00
Jimmy Debe
518717f1c6 Update vac/raw/staking-streamer.md
Co-authored-by: r4bbit <445106+0x-r4bbit@users.noreply.github.com>
2025-06-30 06:58:10 -04:00
Jimmy Debe
711c9e656b Update staking-streamer.md 2025-06-06 07:09:40 -04:00
Jimmy Debe
170ad5dd51 Update staking-streamer.md 2025-06-06 06:58:18 -04:00
Jimmy Debe
97970270b1 Update staking-streamer.md 2025-06-05 10:12:19 -04:00
Jimmy Debe
dc4d1e5d65 Update staking-streamer.md 2025-06-04 21:39:21 -04:00
Jimmy Debe
062d16a02a Update staking-streamer.md 2025-05-30 09:48:23 -04:00
Jimmy Debe
5304b472f4 Create staking-streamer.md 2025-05-20 11:04:36 -04:00
4 changed files with 704 additions and 9 deletions

241
vac/raw/eth-mls-offchain.md Normal file
View File

@@ -0,0 +1,241 @@
---
title: ETH-MLS-OFFCHAIN
name: Secure channel setup using decentralized MLS and Ethereum accounts
status: raw
category: Standards Track
tags:
editor: Ugur Sen [ugur@status.im](mailto:ugur@status.im)
contributors: seemenkina [ekaterina@status.im](mailto:ekaterina@status.im)
---
## Abstract
The following document specifies Ethereum authenticated scalable
and decentralized secure group messaging application by
integrating Message Layer Security (MLS) backend.
Decentralization refers each user is a node in P2P network and
each user has voice for any changes in group.
This is achieved by integrating a consensus mechanism.
Lastly, this RFC can also be referred to as de-MLS,
decentralized MLS, to emphasize its deviation
from the centralized trust assumptions of traditional MLS deployments.
## Motivation
Group messaging is a fundamental part of digital communication,
yet most existing systems depend on centralized servers,
which introduce risks around privacy, censorship, and unilateral control.
In restrictive settings, servers can be blocked or surveilled;
in more open environments, users still face opaque moderation policies,
data collection, and exclusion from decision-making processes.
To address this, we propose a decentralized, scalable peer-to-peer
group messaging system where each participant runs a node, contributes
to message propagation, and takes part in governance autonomously.
Group membership changes are decided collectively through a lightweight
partially synchronous, fault-tolerant consensus protocol without a centralized identity.
This design enables truly democratic group communication and is well-suited
for use cases like activist collectives, research collaborations, DAOs, support groups,
and decentralized social platforms.
## Format Specification
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”,
“SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document
are to be interpreted as described in [2119](https://www.ietf.org/rfc/rfc2119.txt).
### Assumptions
- The nodes in the P2P network can discover other nodes or will connect to other nodes when subscribing to same topic in a gossipsub.
- We MAY have non-reliable (silent) nodes.
- We MUST have a consensus that is lightweight, scalable and finalized in a specific time.
## Roles
The three roles used in de-MLS is as follows:
- `node`: Nodes are members of network without being in any secure group messaging.
- `member`: Members are special nodes in the secure group messaging who
obtains current group key of secure group messaging.
- `steward`: Stewards are special and transparent members in secure group
messaging who organizes the changes upon the voted-proposals.
## MLS Background
The de-MLS consists of MLS backend, so the MLS services and other MLS components
are taken from the original [MLS specification](https://datatracker.ietf.org/doc/rfc9420/), with or without modifications.
### MLS Services
MLS is operated in two services authentication service (AS) and delivery service (DS).
Authentication service enables group members to authenticate the credentials presented by other group members.
The delivery service routes MLS messages among the nodes or
members in the protocol in the correct order and
manage the `keyPackage` of the users where the `keyPackage` is the objects
that provide some public information about a user.
### MLS Objects
Following section presents the MLS objects and components that used in this RFC:
`Epoch`: Fixed time intervals that changes the state that is defined by members,
section 3.4 in [MLS RFC 9420](https://datatracker.ietf.org/doc/rfc9420/).
`MLS proposal message:` Members MUST receive the proposal message prior to the
corresponding commit message that initiates a new epoch with key changes,
in order to ensure the intended security properties, section 12.1 in [MLS RFC 9420](https://datatracker.ietf.org/doc/rfc9420/).
Here, the add and remove proposals are used.
`Application message`: This message type used in arbitrary encrypted communication between group members.
This is restricted by [MLS RFC 9420](https://datatracker.ietf.org/doc/rfc9420/) as if there is pending proposal,
the application message should be cut.
Note that: Since the MLS is based on servers, this delay between proposal and commit messages are very small.
`Commit message:` After members receive the proposals regarding group changes,
the committer, who may be any member of the group, as specified in [MLS RFC 9420](https://datatracker.ietf.org/doc/rfc9420/),
generates the necessary key material for the next epoch, including the appropriate welcome messages
for new joiners and new entropy for removed members. In this RFC, the committers only MUST be stewards.
### de-MLS Objects
`Voting proposal` Similar to MLS proposals, but processed only if approved through a voting process.
They function as application messages in the MLS group,
allowing the steward to collect them without halting the protocol.
## Flow
General flow is as follows:
- A steward initializes a group just once, and then sends out Group Announcements (GA) periodically.
- Meanwhile, each`node`creates and sends their`credential` includes `keyPackage`.
- Each `member`creates `voting proposals` sends them to from MLS group during epoch E.
- Meanwhile, the `steward` collects finalized `voting proposals` from MLS group and converts them into
`MLS proposals` then sends them with correspondng `commit messages`
- Evantually, with the commit messages, all members starts the next epoch E+1.
## Creating Voting Proposal
A `member` MAY initializes the voting with the proposal payload
which is implemented using [protocol buffers v3](https://protobuf.dev/) as follows:
```protobuf
syntax = "proto3";
message Proposal {
string name = 10; // Proposal name
string payload = 11; // Describes the what is voting fore
int32 proposal_id = 12; // Unique identifier of the proposal
bytes proposal_owner = 13; // Public key of the creator
repeated Vote votes = 14; // Vote list in the proposal
int32 expected_voters_count = 15; // Maximum number of distinct voters
int32 round = 16; // Number of Votes
int64 timestamp = 17; // Creation time of proposal
int64 expiration_time = 18; // Time interval that the proposal is active
bool liveness_criteria_yes = 19; // Shows how managing the silent peers vote
}
```
```bash
message Vote {
int32 vote_id = 20; // Unique identifier of the vote
bytes vote_owner = 21; // Voter's public key
int64 timestamp = 22; // Time when the vote was cast
bool vote = 23; // Vote bool value (true/false)
bytes parent_hash = 24; // Hash of previous owner's Vote
bytes received_hash = 25; // Hash of previous received Vote
bytes vote_hash = 26; // Hash of all previously defined fields in Vote
bytes signature = 27; // Signature of vote_hash
}
```
The voting proposal MAY include adding a `node` or removing a `member`.
After the `member` creates the voting proposal,
it is emitted to the network via the MLS `Application message` with a lightweight,
epoch based voting such as [hashgraphlike consensus.](https://github.com/vacp2p/rfc-index/blob/consensus-hashgraph-like/vac/raw/consensus-hashgraphlike.md)
This consensus result MUST be finalized within the epoch as YES or NO.
If the voting result is YES, this points out the voting proposal will be converted into
the MLS proposal by the `steward` and following commit message that starts the new epoch.
## Creating welcome message
When a MLS `MLS proposal message` is created by the `steward`,
a `commit message` SHOULD follow,
as in section 12.04 [MLS RFC 9420](https://datatracker.ietf.org/doc/rfc9420/) to the members.
In order for the new `member` joining the group to synchronize with the current members
who received the `commit message`,
the `steward` sends a welcome message to the node as the new `member`,
as in section 12.4.3.1. [MLS RFC 9420](https://datatracker.ietf.org/doc/rfc9420/).
## Single steward
To naive way to create a decentralized secure group messaging is having a single transparent `steward`
who only applies the changes regarding the result of the voting.
This is mostly similar with the general flow and specified in voting proposal and welcome message creation sections.
1. Each time a single `steward` initializes a group with group parameters with parameters
as in section 8.1. Group Context in [MLS RFC 9420](https://datatracker.ietf.org/doc/rfc9420/).
2. `steward` creates a group anouncement (GA) according to the previous step and
broadcast it to the all network periodically. GA message is visible in network to all `nodes`.
3. The each `node` who wants to be a member needs to obtain this anouncement and create `credential`
includes `keyPackage` that is specified in [MLS RFC 9420](https://datatracker.ietf.org/doc/rfc9420/) section 10.
4. The `steward` aggregates all `KeyPackages` utilizes them to provision group additions for new members,
based on the outcome of the voting process.
5. Any `member` start to create `voting proposals` for adding or removing users,
and present them to the voting in the MLS group as an application message.
However, unlimited use of `voting proposals` within the group may be misused by
malicious or overly active members.
Therefore, an application-level constraint can be introduced to limit the number
or frequency of proposals initiated by each member to prevent spam or abuse.
6. Meanwhile, the `steward` collects finalized `voting proposals` with in epoch `E`,
that have received affirmative votes from members via application messages.
Otherwise, the `steward` discards proposals that did not receive a majority of "YES" votes.
Since voting proposals are transmitted as application messages, omitting them does not affect
the protocols correctness or consistency.
7. The `steward` converts all approved `voting proposals` into
corresponding `MLS proposals` and `commit message`, and
transmits both in a single operation as in [MLS RFC 9420](https://datatracker.ietf.org/doc/rfc9420/) section 12.4,
including welcome messages for the new members. Therefore, the `commit message` ends the previous epoch and create new ones.
## Multi stewards
Decentralization has already been achieved in the previous section.
However, to improve availability and ensure censorship resistance,
the single-steward protocol is extended to a multi-steward architecture.
In this design, each epoch is coordinated by a designated steward,
operating under the same protocol as the single-steward model.
Thus, the multi-steward approach primarily defines how steward roles
rotate across epochs while preserving the underlying structure and logic of the original protocol.
Two variants of the multi-steward design are introduced to address different system requirements.
### Multi steward with single consensus
In this model, all group modifications, such as adding or removing members,
must be approved through consensus by all participants,
including the steward assigned for epoch `E`.
A configuration with multiple stewards operating under a shared consensus protocol offers
increased decentralization and stronger protection against censorship.
However, this benefit comes with reduced operational efficiency.
The model is therefore best suited for small groups that value
decentralization and censorship resistance more than performance.
### Multi steward with two consensuses
The two-consensus model offers improved efficiency with a trade-off in decentralization.
In this design, group changes require consensus only among the stewards, rather than all members.
Regular members participate by periodically selecting the stewards but do not take part in each decision.
This structure enables faster coordination since consensus is achieved within a smaller group of stewards.
It is particularly suitable for large user groups, where involving every member in each decision would be impractical.
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/)
### References
- [MLS RFC 9420](https://datatracker.ietf.org/doc/rfc9420/)
- [Hashgraphlike Consensus](https://github.com/vacp2p/rfc-index/blob/consensus-hashgraph-like/vac/raw/consensus-hashgraphlike.md)
- [vacp2p/de-mls](https://github.com/vacp2p/de-mls)

View File

@@ -55,6 +55,9 @@ but improves scalability by reducing direct interactions between participants.
Each message has a globally unique, immutable ID (or hash).
Messages can be requested from the high-availability caches or
other participants using the corresponding message ID.
* **Participant ID:**
Each participant has a globally unique, immutable ID
visible to other participants in the communication.
## Wire protocol
@@ -75,7 +78,7 @@ message HistoryEntry {
}
message Message {
// 1 Reserved for sender/participant id
string sender_id = 1; // Participant ID of the message sender
string message_id = 2; // Unique identifier of the message
string channel_id = 3; // Identifier of the channel to which the message belongs
optional int32 lamport_timestamp = 10; // Logical timestamp for causal ordering in channel
@@ -85,7 +88,8 @@ message Message {
}
```
Each message MUST include its globally unique identifier in the `message_id` field,
The sending participant MUST include its own globally unique identifier in the `sender_id` field.
In addition, it MUST include a globally unique identifier for the message in the `message_id` field,
likely based on a message hash.
The `channel_id` field MUST be set to the identifier of the channel of group communication
that is being synchronized.
@@ -98,6 +102,10 @@ These fields MAY be left unset in the case of [ephemeral messages](#ephemeral-me
The message `content` MAY be left empty for [periodic sync messages](#periodic-sync-message),
otherwise it MUST contain the application-level content
> **_Note:_** Close readers may notice that, outside of filtering messages originating from the sender itself,
the `sender_id` field is not used for much.
Its importance is expected to increase once a p2p retrieval mechanism is added to SDS, as is planned for the protocol.
### Participant state
Each participant MUST maintain:
@@ -157,6 +165,8 @@ of unacknowledged outgoing messages.
Upon receiving a message,
* the participant SHOULD ignore the message if it has a `sender_id` matching its own.
* the participant MAY deduplicate the message by comparing its `message_id` to previously received message IDs.
* the participant MUST [review the ACK status](#review-ack-status) of messages
in its unacknowledged outgoing buffer
using the received message's causal history and bloom filter.

395
vac/raw/staking-streamer.md Normal file
View File

@@ -0,0 +1,395 @@
---
title: SNT-STAKING-STREAMER
name: Status Network Staking Streamer Protocol
status: raw
category: Standards Track
tags: status-network
editor:
contributors:
- Jimmy Debe <jimmy@status.im>
---
## Abstract
This specification describes the components used for the Status Network Staking Streamer protocol.
The protocol is a set of smart contract protocols currently used in [Status Network](https://status.network/).
## Background/Motivation
Traditional layer 2 blockchains generate revenue from gass fees required to make transactions on the network.
This can introduce a barrier of entry for users wanting to build and
interact with that blockchain.
The Status Network is a layer 2 roll up where applications and
users do not blockchain with gasless transactions.
Revenue is derived from a few sources including native yield commission.
Assests bridged to the Status Network are rehypothecated into yield-bearing equivalents and
users earn an [ERC-20 token](https://eips.ethereum.org/EIPS/eip-20) called Karma.
Karma is an goverance token in the Status Network that gives the user access to a certain throughput of free transactions,
votings and other network benefits.
The SNT token can also be staked with the staking streamer protocol to earn Karma.
The goal is to have a staking mechanism that is fair to all participants based on the stake amount and time staked.
Participants will have significant increases in voting power after committing their stake for a longer period,
even if their stake is not the largest among all participants.
## Specification
The key words “MUST”, “MUST NOT”, “REQUIRED”,
“SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and
“OPTIONAL” in this document are to be interpreted as described in [2119](https://www.ietf.org/rfc/rfc2119.txt).
The staking streamer protocol is a set of smart contracts that implements the staking system.
The protocol consists of the following components:
- accounts
- staking operator
- multipler points
- reward mechanism
- staking vaults
The staking system MUST be supported by an `OPERATOR` who will introduce reward amounts,
reward periods, the token defined by its contract address REQUIRED for use in the system and
making updates to the staking smart contracts.
It is the responsibility of the `OPERATOR` to keep accounts informed about the requirements
and intended changes to the staking system.
### Accounts
Accounts are users who contribute a token, ERC-20 standard, to the staking protocol.
Accounts SHOULD interact with the protocol through a layer-1 blockchain smart contract.
To participate,
users MAY use an external owned account (EOA) and/or a smart account to interact with a `stakeVault` contract.
A `stakeVault` is a smart contract that records and
maintains the current amount of tokens transferred by accounts to the protocol.
Each `stakeVault` MUST have one registered as the owner.
Once registered, the user is considered as an account.
Accounts MAY be the owner of one or more `stakeVault`s.
#### Account Staking Flow
When joining a staking system,
accounts MUST use a `stakeVault` to transfer a token amount to the `stakingManager` contract,
which is described [below](#operator-role).
The account MUST use the same token, identitied by the token address,
as registered in the `stakeVault` by the `OPERATOR`.
Accounts MAY set a predefined duration to lock those tokens.
Tokens will not be retrievable by accounts until the set duration expires.
This is designed to improve the rewards accrued by accounts deciding to lock funds.
After tokens have successfully been transferred to the `stakeVault`,
the account responsible will start to accumulate multiper points.
The rewards and multipler points are described in the [Rewards section](#rewards) below.
If staked tokens are not locked, the account MAY withdraw the full amount of tokens at any time.
### Operator Role
The `OPERATOR` is the owner of the staking system by registering an address on the `stakeManager` contract.
The `OPERATOR` MUST deploy a `stakeManager` smart contract and
facilitate the requirements of the system.
Each account MUST use a `stakeVault` to interact with the `stakeManager`.
This includes transferring to and from the staking system.
The operator MAY set a preferred minimum lock duration for all tokens entering the system.
Accounts transaction MUST fail if the minimum lock duration is not set.
After a minimum lock duration is set,
the operator SHOULD NOT be able to update this amount until the set period is complete.
The `stakeManager` SHOULD be upgradable only by the registered operator.
Contract upgrades will occur when an operator wants to add and/or
change the requirements of the system.
When accounts are aware of changes, either by the operator informing accounts or
accounts reading the blockchain state,
accounts MAY leave the system if they do not agree with the changes.
Including when the operator enables `emergencyMode`.
- The operator decides the amount of rewards that should be awarded to stakers.
- The operator MUST specify the amount of time for rewards to be distributed.
#### Emergency Mode
In some cases,
an operator may choose to stop the functionality of the staking system.
When `emergencyMode` is enabled, the following SHOULD apply:
- new vaults can not register,
- current registered vaults can not stake or stake additional tokens with a lock period,
- operators can not update the global state
- accounts can not claim accrued rewards.
### Rewards
Accounts participate in the staking protocol to earn rewards.
The staking system implements a rewards distribution mechanism,
that works in conjunction with a internal accouting system called multiplier points.
#### Multiplier Points
When accounts have staked for a certain amount of time,
multipler points (MP) are accrued.
The accrued MP is counted toward the account's weight for reward distribution, as described [below](#account-weight).
This ensures that participants are rewarded fairly based on the stake amount
and time staked.
The MP is accumulated over time and MUST not be transferable.
The calculation is based on two factors, Initial MP and Accured MP.
##### Initial MP
Initial MP SHOULD be issued immediately when tokens are staked with or
without a lock-up period.
It is based on the stake amount and lock-up duration.
The formula for Initial MP is derived as follows:
$$
\text{MP}_ \text{Initial} = \text{Stake} \times \left( 1 + \frac{\text{APY} \times T_ \text{lock}}{100 \times T_ \text{year}} \right)
$$
Where:
- $Stake$ = The amount of tokens staked.
- $APY$ = Annual Percentage Yield, set at 100%.
- $T_{lock}$ = Lock-up duration in seconds.
- $T_{year}$ = Total seconds in a year.
This formula calculates the Initial MP issued immediately when tokens are staked with a lock-up period.
The longer the lock-up period, the more MP are issued.
Accounts locking stake MAY earn bonus MP, which MAY be added to the initial MP amount.
For example, Alice stakes 100 tokens with no lock-up time:
$$
\text{MP}_ \text{Initial} = 100 \times \left( 1 + \frac{100 \times 0}{100 \times 365} \right)
$$
$$
\text{MP}_ \text{Initial} = 100 \times \left( 1 + 0\right) = 100
$$
Alice receives 100 MP.
Another example, Alice stakes 100 tokens with a 30 day lock-up period:
$$
\text{MP}_ \text{Initial} = 100 \times \left( 1 + \frac{100 \times 30}{100 \times 365} \right)
$$
$$
\text{MP}_ \text{Initial} = 100 \times \left( 1 + 0.082 \right) = 108.2
$$
Alice receives 108.2 MP.
By locking up the stake for 30 days,
Alice receives an additional 8.2 MP.
Alice cannot access the tokens until the lock-up period has passed.
##### Accrued MP
The Accrued MP SHOULD be accumulated over time as a function of the stake amount,
elapsed time, and annual percentage yield (APY).
The Accrued MP formula is derived as follows:
$$
\text{MP}_ \text{Accrued} = \text{Stake} \times \frac{\text{APY} \times T_ \text{elapsed}}{100 \times T_ \text{year}}
$$
Where:
- $T_{elapsed}$: Time elapsed since staking began, measured in seconds.
This formula adds MP as a function of time,
rewarding accounts with locked stake.
The Accrued MP is calculated based on the stake amount.
Already accrued MP SHOULD not affect the calculation of new accrued MP.
For example, Alice stakes 100 tokens for 15 days:
$$
\text{MP}_ \text{Accrued} = 100 \times \frac{100 \times 15}{100 \times 365} = 4.1
$$
Alice receives 4.1 MP for the 15 days of staked tokens.
This is exactly half of the MP that would have been received if tokens were
locked for 30 days.
Another example, Alice stakes 100 tokens for 30 days:
$$
\text{MP}_ \text{Accrued} = 100 \times \frac{100 \times 30}{100 \times 365} = 8.2
$$
Alice receives 8.2 MP for the 30 days she has staked.
The `stakingManager` contract SHOULD account for all MP accrued by all accounts in the system.
Accounts are REQUIRED to make an on-chain transaction to claim MP.
At any time, accounts MUST be able to retrieve the total MP accrued by the staking system by reading the contract state.
Total MP combines both accrued MP and pending MP.
The accrued MP contains the initial MP and the MP accrued over time.
Pending MP are MP that have yet to be "claimed" by the accounts:
$$
\text{MP}_ \text{Total} = \text{MP}_ \text{Accrued} + \text{MP}_ \text{Pending}
$$
Accounts SHOULD be limited to a total maximum amount of MP that can accrue.
This will prevent accounts from accumulating large amounts of MP over time compared to other accounts.
The maximum amount of MP an account can accrue is capped at:
$$
\text{MP}_\text{Maximum} = \text{MP}_ \text{Initial} + \text{MP}_ \text{Potential}
$$
- $\text{MP}_ \text{Initial}$: The initial MP an account receives when staking, \*_including the bonus MP_.
- $\text{MP}_ \text{Potential}$: The initial MP amount multiplied by a $MAX\_MULTIPLIER$ factor.
- $MAX\_MULTIPLIER$: A constant that determines the multiplier for the maximum amount of MP in the system.
For example, assuming a $MAX\_MULTIPLIER$ of `4`, an account that stakes 100 tokens would have a maximum of:
$$
\mathrm{MP}_{\text{Maximum}} = 100 + (100 \times 4) = 500
$$
This means that the account can never have more than 500 MP,
no matter how long they stake.
#### Reward Distribution
The system distributes rewards based on a few main factors:
- The amount of tokens staked
- The account's Multiplier Points (MP)
- the account's system weight
- The account's reward index
#### Account Weight
Every account in the system has a weight associated with it.
This weight is calculated as the sum of the staked tokens
and the MP:
$$
\text{Account Weight} = \text{Staked Balance} + \text{MP Balance}
$$
In addition, the system MUST track the total weight of all accounts in the system:
$$
\text{Total System Weight} = \sum_{i=1}^{n} \text{Account Weight}_i
$$
The account's MP grows linearly with time,
which means, account weights increase with time, which in turn means,
the total weight of the system increases with time as well.
With the weights mechanism implemented,
the system can now calculate the rewards for each account.
For an individual account,
divide the account's weight by the total system weight and
multiply it by the total reward amount:
$$
\text{Reward Amount} = \text{Account Weight} \times \frac{\text{Total Reward Amount}}{\text{Total System Weight}}
$$
The rewards are calculated in real-time,
they don't actually need to be claimed by any account.
However, whenever an account performs blockchain state change,
such as staking or unstaking funds,
the rewards that have been accrued up to this point are updated in the account's storage.
Any real-time rewards are considered as pending rewards,
until the account interacts with the system.
Pending rewards are calculated as:
$$
\text{Pending Rewards} = \text{Account Weight} \times \left( \text{Current Reward Index} - \text{Account's Last Reward Index} \right)
$$
Rewards are accrued by accounts over time and
SHOULD be available for withdrawal at the end of each reward period.
Based on the reward duration and amount of rewards,
stakers will accrue rewards in real-time based on the rate of rewards which is calculated:
$$
\text{Reward Rate} = \frac{\text{Total Reward Amount}}{\text{Reward Duration}}
$$
- When the `rewardEndTime` period has occurred,
the operator MUST set the new reward ratio.
- account weights increase with
time, which in turn means,
the total weight of the system increases with time as well.
#### Reward Indices
The reward system uses an accounting mechanism based on indices to track and
distribute rewards accurately.
This approach ensures fair distribution even as accounts enter and
exit the system or change their stakes over time.
##### Global Reward Index
The global reward index represents the cumulative rewards per unit of weight since the system's inception.
It increases whenever new rewards are added to the system:
$$
\text{New Index} = \text{Current Index} + \frac{\text{New Rewards} \times \text{Scale Factor}}{\text{Total System Weight}}
$$
Where:
- `Scale Factor` is 1e18 (used for precision)
- `Total System Weight` is the sum of all staked tokens and MP in the system
##### Account Reward Indices
Each account maintains its own reward index,
which represents the point at which they last "claimed" rewards.
The difference between the global index and
an account's index is multiplied by the account's
weight determines their unclaimed rewards:
$$
\text{Unclaimed Rewards} = \text{Account Weight} \times (\text{Global Index} - \text{Account Index})
$$
#### Reward Index Updates
The system MUST update indices in the following situations:
- When new rewards are added by the operator
- When accounts stake or unstake tokens
This mechanism ensures that historical rewards are preserved accurately and
accounts receive their fair share based on their weight over time.
Also, accounts MUST NOT receive the rewards that were accounted for in the system
at the time the account entered the system.
##### Index Adjustment Example
For example, the system has:
- Total Weight: 1000 units
- Current Index: 0.5
- New Rewards: 100 tokens
The index would increase by:
```text
Increase = (100 × 1e18) / 1000 = 0.1e18
New Index = 0.5e18 + 0.1e18 = 0.6e18
```
If an account has:
- Weight: 200 units
- Last Index: 0.5e18
Their unclaimed rewards would be:
```text
Unclaimed = 200 × (0.6e18 - 0.5e18) / 1e18 = 20 tokens
```
## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
## References
- [Status Network](https://status.network/)
- [ERC-20 token](https://eips.ethereum.org/EIPS/eip-20)

View File

@@ -3,9 +3,10 @@ slug: 66
title: 66/WAKU2-METADATA
name: Waku Metadata Protocol
status: draft
editor: Alvaro Revuelta <alrevuelta@status.im>
editor: Franck Royer <franck@status.im>
contributors:
- Filip Dimitrijevic <filip@status.im>
- Filip Dimitrijevic <filip@status.im>
- Alvaro Revuelta <alrevuelta@status.im>
---
## Abstract
@@ -15,16 +16,19 @@ that can be associated with a [10/WAKU2](/waku/standards/core/10/waku2.md) node.
## Metadata Protocol
Waku specifies a req/resp protocol that provides information about the node's medatadata.
Such metadata is meant to be used by the node to decide if a peer is worth connecting
or not.
The keywords “MUST”, // List style “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”,
“NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt).
Waku specifies a req/resp protocol that provides information about the node's capabilities.
Such metadata MAY be used by other peers for subsequent actions such as light protocol requests or disconnection.
The node that makes the request,
includes its metadata so that the receiver is aware of it,
without requiring an extra interaction.
without requiring another round trip.
The parameters are the following:
* `clusterId`: Unique identifier of the cluster that the node is running in.
* `shards`: Shard indexes that the node is subscribed to.
* `shards`: Shard indexes that the node is subscribed to via [`11/WAKU2-RELAY`](/waku/standards/core/11/relay.md).
***Protocol Identifier***
@@ -48,6 +52,51 @@ message WakuMetadataResponse {
}
```
## Implementation Suggestions
### Triggering Metadata Request
A node SHOULD proceed with metadata request upon first connection to a remote node.
A node SHOULD use the remote node's libp2p peer id as identifier for this heuristic.
A node MAY proceed with metadata request upon reconnection to a remote peer.
A node SHOULD store the remote peer's metadata information for future reference.
A node MAY implement a TTL regarding a remote peer's metadata, and refresh it upon expiry by initiating another metadata request.
It is RECOMMENDED to set the TTL to 6 hours.
A node MAY trigger a metadata request after receiving an error response from a remote note
stating they do not support a specific cluster or shard.
For example, when using a request-response service such as [`19/WAKU2-LIGHTPUSH`](/waku/standards/core/19/lightpush.md).
### Providing Cluster Id
A node MUST include their cluster id into their metadata payload.
It is RECOMMENDED for a node to operate on a single cluster id.
### Providing Shard Information
* Nodes that mount [`11/WAKU2-RELAY`](/waku/standards/core/11/relay.md) MAY include the shards they are subscribed to in their metadata payload.
* Shard-relevant services are message related services,
such as [`13/WAKU2-STORE`](/waku/standards/core/13/store.md), [12/WAKU2-FILTER](/waku/standards/core/12/filter.md)
and [`19/WAKU2-LIGHTPUSH`](/waku/standards/core/19/lightpush.md)
but not [`34/WAKU2-PEER-EXCHANGE`](/waku/standards/core/34/peer-exchange.md)
* Nodes that mount [`11/WAKU2-RELAY`](/waku/standards/core/11/relay.md) and a shard-relevant service SHOULD include the shards they are subscribed to in their metadata payload.
* Nodes that do not mount [`11/WAKU2-RELAY`](/waku/standards/core/11/relay.md) SHOULD NOT include any shard information
### Using Cluster Id
When reading the cluster id of a remote peer, the local node MAY disconnect if their cluster id is different from the remote peer.
### Using Shard Information
It is NOT RECOMMENDED to disconnect from a peer based on the fact that their shard information is different from the local node.
Ahead of doing a shard-relevant request,
a node MAY use the previously received metadata shard information to select a peer that support the targeted shard.
For non-shard-relevant requests, a node SHOULD NOT discriminate a peer based on medata shard information.
## Copyright
Copyright and related rights waived via