diff --git a/docs/api/runtime-storage.md b/docs/api/runtime-storage.md new file mode 100644 index 0000000000000000000000000000000000000000..2d8ab2871d102872d6b3658ec24d1d35fca8b153 --- /dev/null +++ b/docs/api/runtime-storage.md @@ -0,0 +1,1235 @@ +# Runtime storage items + +There are **138** storage items from **37** pallets. + +<ul> +<li>System - 0 +<ul> +<li> +<details> +<summary> +<code>Account</code></summary> + The full account information for a particular account ID. +</details> +</li> +<li> +<details> +<summary> +<code>ExtrinsicCount</code></summary> + Total extrinsics count for the current block. +</details> +</li> +<li> +<details> +<summary> +<code>BlockWeight</code></summary> + The current weight for the block. +</details> +</li> +<li> +<details> +<summary> +<code>AllExtrinsicsLen</code></summary> + Total length (in bytes) for all extrinsics put together, for the current block. +</details> +</li> +<li> +<details> +<summary> +<code>BlockHash</code></summary> + Map of block numbers to block hashes. +</details> +</li> +<li> +<details> +<summary> +<code>ExtrinsicData</code></summary> + Extrinsics data for the current block (maps an extrinsic's index to its data). +</details> +</li> +<li> +<details> +<summary> +<code>Number</code></summary> + The current block number being processed. Set by `execute_block`. +</details> +</li> +<li> +<details> +<summary> +<code>ParentHash</code></summary> + Hash of the previous block. +</details> +</li> +<li> +<details> +<summary> +<code>Digest</code></summary> + Digest of the current block, also part of the block header. +</details> +</li> +<li> +<details> +<summary> +<code>Events</code></summary> + Events deposited for the current block. + + NOTE: The item is unbound and should therefore never be read on chain. + It could otherwise inflate the PoV size of a block. + + Events have a large in-memory size. Box the events to not go out-of-memory + just in case someone still reads them from within the runtime. +</details> +</li> +<li> +<details> +<summary> +<code>EventCount</code></summary> + The number of events in the `Events<T>` list. +</details> +</li> +<li> +<details> +<summary> +<code>EventTopics</code></summary> + Mapping between a topic (represented by T::Hash) and a vector of indexes + of events in the `<Events<T>>` list. + + All topic vectors have deterministic storage locations depending on the topic. This + allows light-clients to leverage the changes trie storage tracking mechanism and + in case of changes fetch the list of events of interest. + + The value has the type `(T::BlockNumber, EventIndex)` because if we used only just + the `EventIndex` then in case if the topic has the same contents on the next block + no notification will be triggered thus the event might be lost. +</details> +</li> +<li> +<details> +<summary> +<code>LastRuntimeUpgrade</code></summary> + Stores the `spec_version` and `spec_name` of when the last runtime upgrade happened. +</details> +</li> +<li> +<details> +<summary> +<code>UpgradedToU32RefCount</code></summary> + True if we have upgraded so that `type RefCount` is `u32`. False (default) if not. +</details> +</li> +<li> +<details> +<summary> +<code>UpgradedToTripleRefCount</code></summary> + True if we have upgraded so that AccountInfo contains three types of `RefCount`. False + (default) if not. +</details> +</li> +<li> +<details> +<summary> +<code>ExecutionPhase</code></summary> + The execution phase of the block. +</details> +</li> +</ul> +</li> +<li>Account - 1 +<ul> +<li> +<details> +<summary> +<code>PendingRandomIdAssignments</code></summary> + +</details> +</li> +<li> +<details> +<summary> +<code>PendingNewAccounts</code></summary> + +</details> +</li> +</ul> +</li> +<li>Scheduler - 2 +<ul> +<li> +<details> +<summary> +<code>IncompleteSince</code></summary> + +</details> +</li> +<li> +<details> +<summary> +<code>Agenda</code></summary> + Items to be executed, indexed by the block number that they should be executed on. +</details> +</li> +<li> +<details> +<summary> +<code>Lookup</code></summary> + Lookup from a name to the block number and index of the task. + + For v3 -> v4 the previously unbounded identities are Blake2-256 hashed to form the v4 + identities. +</details> +</li> +</ul> +</li> +<li>Babe - 3 +<ul> +<li> +<details> +<summary> +<code>EpochIndex</code></summary> + Current epoch index. +</details> +</li> +<li> +<details> +<summary> +<code>Authorities</code></summary> + Current epoch authorities. +</details> +</li> +<li> +<details> +<summary> +<code>GenesisSlot</code></summary> + The slot at which the first epoch actually started. This is 0 + until the first block of the chain. +</details> +</li> +<li> +<details> +<summary> +<code>CurrentSlot</code></summary> + Current slot number. +</details> +</li> +<li> +<details> +<summary> +<code>Randomness</code></summary> + The epoch randomness for the *current* epoch. + + # Security + + This MUST NOT be used for gambling, as it can be influenced by a + malicious validator in the short term. It MAY be used in many + cryptographic protocols, however, so long as one remembers that this + (like everything else on-chain) it is public. For example, it can be + used where a number is needed that cannot have been chosen by an + adversary, for purposes such as public-coin zero-knowledge proofs. +</details> +</li> +<li> +<details> +<summary> +<code>PendingEpochConfigChange</code></summary> + Pending epoch configuration change that will be applied when the next epoch is enacted. +</details> +</li> +<li> +<details> +<summary> +<code>NextRandomness</code></summary> + Next epoch randomness. +</details> +</li> +<li> +<details> +<summary> +<code>NextAuthorities</code></summary> + Next epoch authorities. +</details> +</li> +<li> +<details> +<summary> +<code>SegmentIndex</code></summary> + Randomness under construction. + + We make a trade-off between storage accesses and list length. + We store the under-construction randomness in segments of up to + `UNDER_CONSTRUCTION_SEGMENT_LENGTH`. + + Once a segment reaches this length, we begin the next one. + We reset all segments and return to `0` at the beginning of every + epoch. +</details> +</li> +<li> +<details> +<summary> +<code>UnderConstruction</code></summary> + TWOX-NOTE: `SegmentIndex` is an increasing integer, so this is okay. +</details> +</li> +<li> +<details> +<summary> +<code>Initialized</code></summary> + Temporary value (cleared at block finalization) which is `Some` + if per-block initialization has already been called for current block. +</details> +</li> +<li> +<details> +<summary> +<code>AuthorVrfRandomness</code></summary> + This field should always be populated during block processing unless + secondary plain slots are enabled (which don't contain a VRF output). + + It is set in `on_finalize`, before it will contain the value from the last block. +</details> +</li> +<li> +<details> +<summary> +<code>EpochStart</code></summary> + The block numbers when the last and current epoch have started, respectively `N-1` and + `N`. + NOTE: We track this is in order to annotate the block number when a given pool of + entropy was fixed (i.e. it was known to chain observers). Since epochs are defined in + slots, which may be skipped, the block numbers may not line up with the slot numbers. +</details> +</li> +<li> +<details> +<summary> +<code>Lateness</code></summary> + How late the current block is compared to its parent. + + This entry is populated as part of block execution and is cleaned up + on block finalization. Querying this storage entry outside of block + execution context should always yield zero. +</details> +</li> +<li> +<details> +<summary> +<code>EpochConfig</code></summary> + The configuration for the current epoch. Should never be `None` as it is initialized in + genesis. +</details> +</li> +<li> +<details> +<summary> +<code>NextEpochConfig</code></summary> + The configuration for the next epoch, `None` if the config will not change + (you can fallback to `EpochConfig` instead in that case). +</details> +</li> +<li> +<details> +<summary> +<code>SkippedEpochs</code></summary> + A list of the last 100 skipped epochs and the corresponding session index + when the epoch was skipped. + + This is only used for validating equivocation proofs. An equivocation proof + must contains a key-ownership proof for a given session, therefore we need a + way to tie together sessions and epoch indices, i.e. we need to validate that + a validator was the owner of a given key on a given session, and what the + active epoch index was during that session. +</details> +</li> +</ul> +</li> +<li>Timestamp - 4 +<ul> +<li> +<details> +<summary> +<code>Now</code></summary> + Current time for the current block. +</details> +</li> +<li> +<details> +<summary> +<code>DidUpdate</code></summary> + Did the timestamp get updated in this block? +</details> +</li> +</ul> +</li> +<li>Parameters - 5 +<ul> +<li> +<details> +<summary> +<code>ParametersStorage</code></summary> + +</details> +</li> +</ul> +</li> +<li>Balances - 6 +<ul> +<li> +<details> +<summary> +<code>TotalIssuance</code></summary> + The total units issued in the system. +</details> +</li> +<li> +<details> +<summary> +<code>InactiveIssuance</code></summary> + The total units of outstanding deactivated balance in the system. +</details> +</li> +<li> +<details> +<summary> +<code>Account</code></summary> + The Balances pallet example of storing the balance of an account. + + # Example + + ```nocompile + impl pallet_balances::Config for Runtime { + type AccountStore = StorageMapShim<Self::Account<Runtime>, frame_system::Provider<Runtime>, AccountId, Self::AccountData<Balance>> + } + ``` + + You can also store the balance of an account in the `System` pallet. + + # Example + + ```nocompile + impl pallet_balances::Config for Runtime { + type AccountStore = System + } + ``` + + But this comes with tradeoffs, storing account balances in the system pallet stores + `frame_system` data alongside the account data contrary to storing account balances in the + `Balances` pallet, which uses a `StorageMap` to store balances data only. + NOTE: This is only used in the case that this pallet is used to store balances. +</details> +</li> +<li> +<details> +<summary> +<code>Locks</code></summary> + Any liquidity locks on some account balances. + NOTE: Should only be accessed when setting, changing and freeing a lock. +</details> +</li> +<li> +<details> +<summary> +<code>Reserves</code></summary> + Named reserves on some account balances. +</details> +</li> +<li> +<details> +<summary> +<code>Holds</code></summary> + Holds on account balances. +</details> +</li> +<li> +<details> +<summary> +<code>Freezes</code></summary> + Freeze locks on account balances. +</details> +</li> +</ul> +</li> +<li>TransactionPayment - 32 +<ul> +<li> +<details> +<summary> +<code>NextFeeMultiplier</code></summary> + +</details> +</li> +<li> +<details> +<summary> +<code>StorageVersion</code></summary> + +</details> +</li> +</ul> +</li> +<li>OneshotAccount - 7 +<ul> +<li> +<details> +<summary> +<code>OneshotAccounts</code></summary> + +</details> +</li> +</ul> +</li> +<li>Quota - 66 +<ul> +<li> +<details> +<summary> +<code>IdtyQuota</code></summary> + maps identity index to quota +</details> +</li> +<li> +<details> +<summary> +<code>RefundQueue</code></summary> + fees waiting for refund +</details> +</li> +</ul> +</li> +<li>AuthorityMembers - 10 +<ul> +<li> +<details> +<summary> +<code>AccountIdOf</code></summary> + maps member id to account id +</details> +</li> +<li> +<details> +<summary> +<code>AuthoritiesCounter</code></summary> + count the number of authorities +</details> +</li> +<li> +<details> +<summary> +<code>IncomingAuthorities</code></summary> + list incoming authorities +</details> +</li> +<li> +<details> +<summary> +<code>OnlineAuthorities</code></summary> + list online authorities +</details> +</li> +<li> +<details> +<summary> +<code>OutgoingAuthorities</code></summary> + list outgoing authorities +</details> +</li> +<li> +<details> +<summary> +<code>Members</code></summary> + maps member id to member data +</details> +</li> +<li> +<details> +<summary> +<code>BlackList</code></summary> + +</details> +</li> +</ul> +</li> +<li>Authorship - 11 +<ul> +<li> +<details> +<summary> +<code>Author</code></summary> + Author of current block. +</details> +</li> +</ul> +</li> +<li>Offences - 12 +<ul> +<li> +<details> +<summary> +<code>Reports</code></summary> + The primary structure that holds all offence records keyed by report identifiers. +</details> +</li> +<li> +<details> +<summary> +<code>ConcurrentReportsIndex</code></summary> + A vector of reports of the same kind that happened at the same time slot. +</details> +</li> +</ul> +</li> +<li>Historical - 13 +<ul> +</ul> +</li> +<li>Session - 14 +<ul> +<li> +<details> +<summary> +<code>Validators</code></summary> + The current set of validators. +</details> +</li> +<li> +<details> +<summary> +<code>CurrentIndex</code></summary> + Current index of the session. +</details> +</li> +<li> +<details> +<summary> +<code>QueuedChanged</code></summary> + True if the underlying economic identities or weighting behind the validators + has changed in the queued validator set. +</details> +</li> +<li> +<details> +<summary> +<code>QueuedKeys</code></summary> + The queued keys for the next session. When the next session begins, these keys + will be used to determine the validator's session keys. +</details> +</li> +<li> +<details> +<summary> +<code>DisabledValidators</code></summary> + Indices of disabled validators. + + The vec is always kept sorted so that we can find whether a given validator is + disabled using binary search. It gets cleared when `on_session_ending` returns + a new set of identities. +</details> +</li> +<li> +<details> +<summary> +<code>NextKeys</code></summary> + The next session keys for a validator. +</details> +</li> +<li> +<details> +<summary> +<code>KeyOwner</code></summary> + The owner of a key. The key is the `KeyTypeId` + the encoded key. +</details> +</li> +</ul> +</li> +<li>Grandpa - 15 +<ul> +<li> +<details> +<summary> +<code>State</code></summary> + State of the current authority set. +</details> +</li> +<li> +<details> +<summary> +<code>PendingChange</code></summary> + Pending change: (signaled at, scheduled change). +</details> +</li> +<li> +<details> +<summary> +<code>NextForced</code></summary> + next block number where we can force a change. +</details> +</li> +<li> +<details> +<summary> +<code>Stalled</code></summary> + `true` if we are currently stalled. +</details> +</li> +<li> +<details> +<summary> +<code>CurrentSetId</code></summary> + The number of changes (both in terms of keys and underlying economic responsibilities) + in the "set" of Grandpa validators from genesis. +</details> +</li> +<li> +<details> +<summary> +<code>SetIdSession</code></summary> + A mapping from grandpa set ID to the index of the *most recent* session for which its + members were responsible. + + This is only used for validating equivocation proofs. An equivocation proof must + contains a key-ownership proof for a given session, therefore we need a way to tie + together sessions and GRANDPA set ids, i.e. we need to validate that a validator + was the owner of a given key on a given session, and what the active set ID was + during that session. + + TWOX-NOTE: `SetId` is not under user control. +</details> +</li> +</ul> +</li> +<li>ImOnline - 16 +<ul> +<li> +<details> +<summary> +<code>HeartbeatAfter</code></summary> + The block number after which it's ok to send heartbeats in the current + session. + + At the beginning of each session we set this to a value that should fall + roughly in the middle of the session duration. The idea is to first wait for + the validators to produce a block in the current session, so that the + heartbeat later on will not be necessary. + + This value will only be used as a fallback if we fail to get a proper session + progress estimate from `NextSessionRotation`, as those estimates should be + more accurate then the value we calculate for `HeartbeatAfter`. +</details> +</li> +<li> +<details> +<summary> +<code>Keys</code></summary> + The current set of keys that may issue a heartbeat. +</details> +</li> +<li> +<details> +<summary> +<code>ReceivedHeartbeats</code></summary> + For each session index, we keep a mapping of `SessionIndex` and `AuthIndex` to + `WrapperOpaque<BoundedOpaqueNetworkState>`. +</details> +</li> +<li> +<details> +<summary> +<code>AuthoredBlocks</code></summary> + For each session index, we keep a mapping of `ValidatorId<T>` to the + number of blocks authored by the given authority. +</details> +</li> +</ul> +</li> +<li>AuthorityDiscovery - 17 +<ul> +</ul> +</li> +<li>Sudo - 20 +<ul> +<li> +<details> +<summary> +<code>Key</code></summary> + The `AccountId` of the sudo key. +</details> +</li> +</ul> +</li> +<li>UpgradeOrigin - 21 +<ul> +</ul> +</li> +<li>Preimage - 22 +<ul> +<li> +<details> +<summary> +<code>StatusFor</code></summary> + The request status of a given hash. +</details> +</li> +<li> +<details> +<summary> +<code>PreimageFor</code></summary> + +</details> +</li> +</ul> +</li> +<li>TechnicalCommittee - 23 +<ul> +<li> +<details> +<summary> +<code>Proposals</code></summary> + The hashes of the active proposals. +</details> +</li> +<li> +<details> +<summary> +<code>ProposalOf</code></summary> + Actual proposal for a given hash, if it's current. +</details> +</li> +<li> +<details> +<summary> +<code>Voting</code></summary> + Votes on a given proposal, if it is ongoing. +</details> +</li> +<li> +<details> +<summary> +<code>ProposalCount</code></summary> + Proposals so far. +</details> +</li> +<li> +<details> +<summary> +<code>Members</code></summary> + The current members of the collective. This is stored sorted (just by value). +</details> +</li> +<li> +<details> +<summary> +<code>Prime</code></summary> + The prime member that helps determine the default vote behavior in case of absentations. +</details> +</li> +</ul> +</li> +<li>UniversalDividend - 30 +<ul> +<li> +<details> +<summary> +<code>CurrentUd</code></summary> + Current UD amount +</details> +</li> +<li> +<details> +<summary> +<code>CurrentUdIndex</code></summary> + Current UD index +</details> +</li> +<li> +<details> +<summary> +<code>MonetaryMass</code></summary> + Total quantity of money created by universal dividend (does not take into account the possible destruction of money) +</details> +</li> +<li> +<details> +<summary> +<code>NextReeval</code></summary> + Next UD reevaluation +</details> +</li> +<li> +<details> +<summary> +<code>NextUd</code></summary> + Next UD creation +</details> +</li> +<li> +<details> +<summary> +<code>PastReevals</code></summary> + Past UD reevaluations +</details> +</li> +</ul> +</li> +<li>Wot - 40 +<ul> +</ul> +</li> +<li>Identity - 41 +<ul> +<li> +<details> +<summary> +<code>Identities</code></summary> + maps identity index to identity value +</details> +</li> +<li> +<details> +<summary> +<code>CounterForIdentities</code></summary> +Counter for the related counted storage map +</details> +</li> +<li> +<details> +<summary> +<code>IdentityIndexOf</code></summary> + maps account id to identity index +</details> +</li> +<li> +<details> +<summary> +<code>IdentitiesNames</code></summary> + maps identity name to identity index (simply a set) +</details> +</li> +<li> +<details> +<summary> +<code>NextIdtyIndex</code></summary> + counter of the identity index to give to the next identity +</details> +</li> +<li> +<details> +<summary> +<code>IdentitiesRemovableOn</code></summary> + maps block number to the list of identities set to be removed at this bloc +</details> +</li> +</ul> +</li> +<li>Membership - 42 +<ul> +<li> +<details> +<summary> +<code>Membership</code></summary> + maps identity id to membership data +</details> +</li> +<li> +<details> +<summary> +<code>CounterForMembership</code></summary> +Counter for the related counted storage map +</details> +</li> +<li> +<details> +<summary> +<code>MembershipsExpireOn</code></summary> + maps block number to the list of identity id set to expire at this block +</details> +</li> +<li> +<details> +<summary> +<code>PendingMembership</code></summary> + identities with pending membership request +</details> +</li> +<li> +<details> +<summary> +<code>PendingMembershipsExpireOn</code></summary> + maps block number to the list of memberships set to expire at this block +</details> +</li> +</ul> +</li> +<li>Cert - 43 +<ul> +<li> +<details> +<summary> +<code>StorageIdtyCertMeta</code></summary> + Certifications metada by issuer +</details> +</li> +<li> +<details> +<summary> +<code>CertsByReceiver</code></summary> + Certifications by receiver +</details> +</li> +<li> +<details> +<summary> +<code>StorageCertsRemovableOn</code></summary> + Certifications removable on +</details> +</li> +</ul> +</li> +<li>Distance - 44 +<ul> +<li> +<details> +<summary> +<code>EvaluationPool0</code></summary> + Identities queued for distance evaluation +</details> +</li> +<li> +<details> +<summary> +<code>EvaluationPool1</code></summary> + Identities queued for distance evaluation +</details> +</li> +<li> +<details> +<summary> +<code>EvaluationPool2</code></summary> + Identities queued for distance evaluation +</details> +</li> +<li> +<details> +<summary> +<code>EvaluationBlock</code></summary> + Block for which the distance rule must be checked +</details> +</li> +<li> +<details> +<summary> +<code>IdentityDistanceStatus</code></summary> + Distance evaluation status by identity + + * `.0` is the account who requested an evaluation and reserved the price, + for whom the price will be unreserved or slashed when the evaluation completes. + * `.1` is the status of the evaluation. +</details> +</li> +<li> +<details> +<summary> +<code>DistanceStatusExpireOn</code></summary> + Identities by distance status expiration session index +</details> +</li> +<li> +<details> +<summary> +<code>DidUpdate</code></summary> + Did evaluation get updated in this block? +</details> +</li> +</ul> +</li> +<li>SmithSubWot - 50 +<ul> +</ul> +</li> +<li>SmithMembership - 52 +<ul> +<li> +<details> +<summary> +<code>Membership</code></summary> + maps identity id to membership data +</details> +</li> +<li> +<details> +<summary> +<code>CounterForMembership</code></summary> +Counter for the related counted storage map +</details> +</li> +<li> +<details> +<summary> +<code>MembershipsExpireOn</code></summary> + maps block number to the list of identity id set to expire at this block +</details> +</li> +<li> +<details> +<summary> +<code>PendingMembership</code></summary> + identities with pending membership request +</details> +</li> +<li> +<details> +<summary> +<code>PendingMembershipsExpireOn</code></summary> + maps block number to the list of memberships set to expire at this block +</details> +</li> +</ul> +</li> +<li>SmithCert - 53 +<ul> +<li> +<details> +<summary> +<code>StorageIdtyCertMeta</code></summary> + Certifications metada by issuer +</details> +</li> +<li> +<details> +<summary> +<code>CertsByReceiver</code></summary> + Certifications by receiver +</details> +</li> +<li> +<details> +<summary> +<code>StorageCertsRemovableOn</code></summary> + Certifications removable on +</details> +</li> +</ul> +</li> +<li>AtomicSwap - 60 +<ul> +<li> +<details> +<summary> +<code>PendingSwaps</code></summary> + +</details> +</li> +</ul> +</li> +<li>Multisig - 61 +<ul> +<li> +<details> +<summary> +<code>Multisigs</code></summary> + The set of open multisig operations. +</details> +</li> +</ul> +</li> +<li>ProvideRandomness - 62 +<ul> +<li> +<details> +<summary> +<code>NexEpochHookIn</code></summary> + +</details> +</li> +<li> +<details> +<summary> +<code>RequestIdProvider</code></summary> + +</details> +</li> +<li> +<details> +<summary> +<code>RequestsReadyAtNextBlock</code></summary> + +</details> +</li> +<li> +<details> +<summary> +<code>RequestsReadyAtEpoch</code></summary> + +</details> +</li> +<li> +<details> +<summary> +<code>RequestsIds</code></summary> + +</details> +</li> +<li> +<details> +<summary> +<code>CounterForRequestsIds</code></summary> +Counter for the related counted storage map +</details> +</li> +</ul> +</li> +<li>Proxy - 63 +<ul> +<li> +<details> +<summary> +<code>Proxies</code></summary> + The set of account proxies. Maps the account which has delegated to the accounts + which are being delegated to, together with the amount held on deposit. +</details> +</li> +<li> +<details> +<summary> +<code>Announcements</code></summary> + The announcements made by the proxy (key). +</details> +</li> +</ul> +</li> +<li>Utility - 64 +<ul> +</ul> +</li> +<li>Treasury - 65 +<ul> +<li> +<details> +<summary> +<code>ProposalCount</code></summary> + Number of proposals that have been made. +</details> +</li> +<li> +<details> +<summary> +<code>Proposals</code></summary> + Proposals that have been made. +</details> +</li> +<li> +<details> +<summary> +<code>Deactivated</code></summary> + The amount which has been reported as inactive to Currency. +</details> +</li> +<li> +<details> +<summary> +<code>Approvals</code></summary> + Proposal indices that have been approved but not yet awarded. +</details> +</li> +</ul> +</li> +</ul> \ No newline at end of file diff --git a/xtask/res/templates/runtime-storages.md b/xtask/res/templates/runtime-storages.md new file mode 100644 index 0000000000000000000000000000000000000000..0891e57cda2dbb7a1814625d433d32df8002b04b --- /dev/null +++ b/xtask/res/templates/runtime-storages.md @@ -0,0 +1,21 @@ +# Runtime storage items + +There are **{{storage_counter}}** storage items from **{{ pallets | length }}** pallets. + +<ul> +{% for pallet in pallets -%} +<li>{{ pallet.name }} - {{ pallet.index }} +<ul> +{% for storage in pallet.storages -%} +<li> +<details> +<summary> +<code>{{ storage.name }}{#({{ storage.key }}→{{ storage.value }})#}</code></summary> +{{ storage.documentation }} +</details> +</li> +{% endfor -%} +</ul> +</li> +{% endfor -%} +</ul> \ No newline at end of file diff --git a/xtask/src/gen_doc.rs b/xtask/src/gen_doc.rs index cbda42494f57b169e3332ee3d67fd9403fb917c4..4513910abbdc5d3e422b836cc649a3f2defc6b1d 100644 --- a/xtask/src/gen_doc.rs +++ b/xtask/src/gen_doc.rs @@ -16,6 +16,7 @@ use anyhow::{bail, Context, Result}; use codec::Decode; +use frame_metadata::{StorageEntryMetadata, StorageEntryType}; use scale_info::form::PortableForm; use serde::Serialize; use std::{ @@ -29,6 +30,7 @@ use tera::Tera; const CALLS_DOC_FILEPATH: &str = "docs/api/runtime-calls.md"; const EVENTS_DOC_FILEPATH: &str = "docs/api/runtime-events.md"; const ERRORS_DOC_FILEPATH: &str = "docs/api/runtime-errors.md"; +const STORAGES_DOC_FILEPATH: &str = "docs/api/runtime-storage.md"; const TEMPLATES_GLOB: &str = "xtask/res/templates/*.md"; // define structs and implementations @@ -42,6 +44,7 @@ struct Pallet { calls: Vec<Call>, events: Vec<Event>, errors: Vec<ErroR>, + storages: Vec<Storage>, } #[derive(Clone, Serialize)] struct Call { @@ -73,6 +76,18 @@ struct ErroR { index: u8, name: String, } +#[derive(Clone, Serialize)] +struct Storage { + documentation: String, + name: String, + key: Option<String>, + value: String, +} +#[derive(Clone, Serialize)] +struct StorageMap { + name: String, + type_name: String, +} impl Pallet { fn new( @@ -81,6 +96,7 @@ impl Pallet { call_scale_type_def: &Option<scale_info::TypeDef<PortableForm>>, event_scale_type_def: &Option<scale_info::TypeDef<PortableForm>>, error_scale_type_def: &Option<scale_info::TypeDef<PortableForm>>, + storage_entries: &Option<Vec<StorageEntryMetadata<PortableForm>>>, ) -> Result<Self> { let calls = if let Some(call_scale_type_def) = call_scale_type_def { if let scale_info::TypeDef::Variant(calls_enum) = call_scale_type_def { @@ -109,12 +125,18 @@ impl Pallet { } else { vec![] }; + let storages = if let Some(storage_entries) = storage_entries { + storage_entries.iter().map(Into::into).collect() + } else { + vec![] + }; Ok(Self { index, name, calls, events, errors, + storages, }) } } @@ -163,6 +185,23 @@ impl From<&scale_info::Field<PortableForm>> for EventParam { } } +impl From<&StorageEntryMetadata<PortableForm>> for Storage { + fn from(entry: &StorageEntryMetadata<PortableForm>) -> Self { + let (key, value) = match entry.ty { + StorageEntryType::<PortableForm>::Plain(v) => (None, format!("{}", v.id)), + StorageEntryType::<PortableForm>::Map { key, value, .. } => { + (Some(format!("{}", key.id)), format!("{}", value.id)) + } + }; + Self { + documentation: entry.docs.iter().cloned().collect::<Vec<_>>().join("\n"), + name: entry.name.to_owned(), + key, + value, + } + } +} + impl From<&scale_info::Variant<PortableForm>> for ErroR { fn from(variant: &scale_info::Variant<PortableForm>) -> Self { Self { @@ -244,7 +283,7 @@ pub(super) fn gen_doc() -> Result<()> { bail!("unsuported metadata version") }; - let (call_doc, event_doc, error_doc) = print_runtime(runtime); + let (call_doc, event_doc, error_doc, storage_doc) = print_runtime(runtime); let mut file = File::create(CALLS_DOC_FILEPATH) .with_context(|| format!("Failed to create file '{}'", CALLS_DOC_FILEPATH))?; @@ -258,6 +297,10 @@ pub(super) fn gen_doc() -> Result<()> { .with_context(|| format!("Failed to create file '{}'", ERRORS_DOC_FILEPATH))?; file.write_all(error_doc.as_bytes()) .with_context(|| format!("Failed to write to file '{}'", ERRORS_DOC_FILEPATH))?; + let mut file = File::create(STORAGES_DOC_FILEPATH) + .with_context(|| format!("Failed to create file '{}'", STORAGES_DOC_FILEPATH))?; + file.write_all(storage_doc.as_bytes()) + .with_context(|| format!("Failed to write to file '{}'", STORAGES_DOC_FILEPATH))?; Ok(()) } @@ -295,6 +338,12 @@ fn get_from_metadata_v14( println!("{}: {} (0 errors)", pallet.index, pallet.name); None }; + let storage_entries = if let Some(storages) = pallet.storage { + Some(storages.entries) + } else { + println!("{}: {} (0 storages)", pallet.index, pallet.name); + None + }; let pallet = Pallet::new( pallet.index, @@ -302,6 +351,7 @@ fn get_from_metadata_v14( &calls_type_def, &events_type_def, &errors_type_def, + &storage_entries, )?; println!( @@ -322,13 +372,19 @@ fn get_from_metadata_v14( pallet.name, pallet.errors.len() ); + println!( + "{}: {} ({} storages)", + pallet.index, + pallet.name, + pallet.storages.len() + ); pallets.push(pallet); } Ok(pallets) } /// use template to render markdown file with runtime calls documentation -fn print_runtime(pallets: RuntimePallets) -> (String, String, String) { +fn print_runtime(pallets: RuntimePallets) -> (String, String, String, String) { // init variables let mut user_calls_counter = 0; let user_calls_pallets: RuntimePallets = pallets @@ -392,6 +448,11 @@ fn print_runtime(pallets: RuntimePallets) -> (String, String, String) { .iter() .for_each(|pallet| error_counter += pallet.errors.len()); + let mut storage_counter = 0; + pallets + .iter() + .for_each(|pallet| storage_counter += pallet.storages.len()); + // compile template let tera = match Tera::new(TEMPLATES_GLOB) { Ok(t) => t, @@ -427,5 +488,11 @@ fn print_runtime(pallets: RuntimePallets) -> (String, String, String) { .render("runtime-errors.md", &context) .expect("template error"); - (call_doc, event_doc, error_doc) + // render storages + context.insert("storage_counter", &storage_counter); + let storage_doc = tera + .render("runtime-storages.md", &context) + .expect("template storage"); + + (call_doc, event_doc, error_doc, storage_doc) }