Repository navigation
Dash Platform v5.0.0
Executive Summary
Dash Platform 5.0 introduces protocol version 14, which gives applications the tools to run communities and markets on Platform itself:
- Document references and rules that Platform enforces between documents, identities, keys and contracts.
- Index-only document types and new ranked, time-windowed, composite and chained queries, each answered with a single proof.
- Action fees paid to contract owners and moderators.
- Identity keys scoped to an app, with budgets and expiry dates.
- Contract moderation with banlists, moderators and elected moderation teams.
Withdrawals move to a limit relative to the credits Platform holds, kept within what Dash Core will release, and Platform is ready for Dash Core v24. The release cycle also included extensive hardening of block execution, proof verification and the SDKs.
The new protocol rules take effect only once mainnet activates protocol version 14 (see Upgrading).
Key Improvements and Capabilities
1. Richer Data Contracts
Platform 5.0 lets a data contract declare much more about its documents, and consensus enforces it on every write. These keywords are accepted only from protocol version 14, and most are fixed once registered: a contract update may not add, change or remove them.
1.1 References (refersTo)
An identifier property, or each element of a typed array of identifiers, can declare what it refers to. Platform checks the target on create, and on a replace when the result could have changed.
| Target | The value must be | Options |
|---|---|---|
identity, token |
an existing identity or token | |
contract |
an existing data contract | contractRequirements: moderation, minimumAgeSeconds, minimumSecondsSinceUpdate, owner, readonly, keepsHistory, ownerProtected |
permanentDocument |
a document of a type whose documents never disappear | documentType, contractId, where, findBy, inList |
moderatedDocument |
a document only moderators remove, on the record | documentType, contractId, where |
deletableDocument |
a document that may disappear; checked on every replace | documentType, contractId, where, findBy, consume, constraints |
identityPublicKey |
an enabled identity key | keyIdProperty or identityProperty, keyRequirements (purpose, boundTo) |
whereadds conditions on the referenced document: equality with a referring property or the writer ("$ownerId"),const,notEqual,in, integer orderings, and list comparisons for typed arrays.findByfinds the target through a unique index, the value being one key part (an identity, a string or bytes rather than a document id).- Commit and reveal: a
findByentry may besys.hash.sha256dof the new document's values.minimumAgeBlocksrequires an older commitment,consumedeletes it with the create, andchooseFirstrefuses a reveal while another identity's valid, unexpired commitment to the same value came first. inListrequires the value to be in a list on a permanent document;anyOf/allOfcombine 2 to 4 operands;ownerRefersTo/creatorRefersToapply a declaration to the writer or the creator.- A document carries at most 256 references (a typed array counts its
maxItems), each a billed read.
1.2 Rules Between Properties (propertyConstraints)
Named rules relate a document's properties: { "lessThanOrEqual": [{ "multiply": ["price", "quantity"] }, "deposit"] }. They are judged on every create and replace, and on transfers, purchases and price updates that change what they read (10422 when broken). Arithmetic is exact 128-bit integer math; floats cannot be read.
| Family | Operators and operands |
|---|---|
| Comparison | equal, notEqual, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual |
| Membership and text | in, notIn, contains (typed arrays), startsWith, endsWith (strings, byte arrays) |
| Logic | anyOf, allOf, not, ifThen, ifThenElse, present, absent |
| Arithmetic | add, subtract, multiply, divide, modulo, power, min, max, abs |
| Sizes and bytes | length, byteLength, count, countPresent, byteAt |
| Values | properties, { "const": ... }, ifAbsent, $ownerId, system times and heights, $revision, the stored version via $old. |
| State | countOf, sumOf (count and sum tree totals), referenced (a field of a referenced document) |
A type declares at most 16 rules of at most 32 nodes each, reading at most 4 distinct totals.
1.3 Mutability and Lifecycle
| Keyword | Effect |
|---|---|
immutable |
Properties a replace may not change, always or { "property", "when" } while a condition holds. Updates may add entries, never remove them |
requiredSince |
A contract update may add a required property; documents written under older contract versions stay valid |
deleteConstraints |
Rules the stored document must meet for its owner to delete it, such as "no vote names this poll" (40147) |
canBeDeleted: "onlyWhenConsumed" |
The owner cannot delete; a create that consumes the document can |
outlivesDelete |
An indexOnly type's timeRange entries outlive a delete until their window expires |
ttl |
Platform deletes the document ttl seconds after $createdAt |
A type that keeps history must now set canBeDeleted: false.
1.4 Documents with a Time to Live
ttl is 3,600 (one hour) to 31,536,000 (one year) seconds. It requires $createdAt and excludes documentsKeepHistory, indexOnly and contested indexes. Platform deletes expired documents after each block's transitions, at most 128 per block. An expired document can no longer be replaced, transferred, bought or repriced (40140).
These documents refund nothing. Each byte pays for the lifetime left: 1 credit up to an hour, 4 up to a day, 8 up to two days, 15 up to four, 26 up to seven, then 34 per 9.125 days. The create prepays its deletion: 1,200,000 credits, 400,000 per index level and 420 per document byte.
1.5 New Property Kinds and Keywords
| Keyword | What it declares |
|---|---|
Typed arrays (items) |
Lists of integers, numbers, strings, booleans, byte arrays or identifiers, maxItems at most 1,024; elements can be indexed |
identifier, bytes + size |
Shorthand types for a 32-byte identifier and a fixed-size byte array |
maxBytes |
UTF-8 byte cap on a string, 1 to 65,535 |
distinctFrom |
An identifier differs from another identifier property or $ownerId |
encryptedFor |
A byte array is ciphertext for a recipient, naming the keys and scheme (ecdh-secp256k1-aes256-cbc) |
generatedFrom |
Platform generates a string from other properties: lowercase, uppercase, capitalize, camelCase, snakeCase, homographSafeASCII |
integerRange |
An index buckets an integer property into windows |
"<reference>.<field>" |
An index property holding a referenced document's value, such as postId.$ownerId |
skipIfAbsent |
An index skips documents missing its optional (true) or listed properties |
1.6 Document Ids and Other Rules
- A document id now also hashes the identity contract nonce of its create, so a deleted document's id can never be reused for other content. Clients must derive ids with the nonce, as the 5.0 SDKs do; an old-style id is refused (
InvalidDocumentTransitionIdError). - A contested or
ttltype summing a property must bound it to ±2^27 (attltype may instead setminimumto 0 or more). - New property and document type names accept only letters, digits and underscores.
2. Index-Only Types and Advanced Queries
Platform 5.0 lets a contract store small records, such as likes or follows, as nothing but index entries, and adds new query shapes: top-K leaderboards, totals per time window, matches on list elements, and a feed page fetched together with the queries it depends on. Each of them can be proved. The schema keywords and most query shapes take effect with protocol version 14; composite queries, contract listing and contract version checks are served by any 5.0 node.
2.1 Index-Only Document Types (protocol 14)
An indexOnly: true type stores no document body and no primary-tree row: its index entries are its documents. Each entry is keyed by the index values and a member key from the index's terminal (default $ownerId, or up to 10 properties), and holds a 32-byte row commitment that ties one document's entries together. An index therefore acts as a uniqueness rule: [postId] with terminal $ownerId allows one like per post and identity.
| Keyword | Effect |
|---|---|
terminal |
The member key. An index with no properties is a flat key-value index |
entryPayload |
Up to 16 unindexed properties stored in each entry and returned with every result |
skipIfAbsent |
A document missing a skip property writes nothing to the index (also available on ordinary types, at any position) |
preallocated |
Creating the referenced document creates the index trees, so a post with no likes still ranks with zero |
summableOffCountIndex |
One counter per group, holding another index's entry count, instead of an entry per document |
outlivesDelete |
On a timeRange index with a ttl, a delete leaves the entries to expire with their window |
Documents can only be created and deleted. A delete uses the new indexOnlyDelete batch transition, which carries the document's values (there is no $id to address) and must match the row commitment. Queries return documents rebuilt from one index's entries and page by a range on the terminal.
2.2 Ranked Indexes and Top-K (protocol 14)
rankedCountable, rankedSummable and rankedAverageable keep an ordered view of an index's per-group totals, so SELECT count(*) ... GROUP BY hashtag ORDER BY count(*) DESC LIMIT 10 reads 10 entries in O(log n + k) rather than every group, with a proof that grows with K. A compound index keeps one ranking per prefix value; the { "at": [...] } form ranks an earlier level by the documents beneath it (hashtags by total posts). The limit is 1 to 100, the offset is skipped by counting, and one leading pin may be an IN of 2 to 10 values whose rankings are merged. A boolean HAVING <agg> <op> <value> with one range operator returns the groups whose total falls in the range, from the same ranking.
2.3 Time and Value Windows (protocol 14)
timeRange: { on, range, step, phase, ttl } buckets $createdAt, $updatedAt or $transferredAt into windows; with overlapping windows a document falls in at most 24 of them. Totals and rankings below the bucket give one leaderboard per window. A query selects one window with IN_TIME_RANGE: NEWEST, OLDEST (the trailing near-full window, for "trending") or BY_START. The node resolves relative selectors from block time and the verifier re-derives them from the quorum-signed response time. A ttl of at most one week expires old windows: they cannot be queried, later writes drain them, and bytes under the index are billed as processing at 270 credits per byte (1% of the storage rate) with no refund. integerRange applies the same windowing, without ttl, to an integer property, selected with IN_INTEGER_RANGE.
2.4 Element Indexes and More Filters (protocol 14)
- Typed array elements: an index may name a typed array, entering the document once per distinct element.
CONTAINSmatches one element;CONTAINS_ANYtakes 1 to 100 values. Totals are per element. - Multiple
INclauses on consecutive index properties of a documents query, with the product of list sizes at most 100. - Unsigned integers in value order: index keys of contract-defined unsigned integer properties now sort numerically, so ranges and ordering follow value order; activation re-keys existing entries (a property that ends a
rangeSummableindex keeps its keys).
2.5 Composite and Chained Queries
Both are modes of the getDocuments V1 request and return one merged GroveDB proof over one state root. The verifier re-derives every derived clause from the proven results, so the node cannot alter the composition.
| Mode | What it does |
|---|---|
Composite (sub_queries) |
A page (limit required, at most 100) plus up to 10 sub-queries: by-id joins through refersTo, lookups by $ownerId or an indexed property (in any contract) and per-value counts, each with an IN clause derived from the page or an earlier sub-query, or unbound sibling queries. Any 5.0 node; by-id joins need protocol 14 references |
Chained (chained) |
A semi-join such as "posts I liked": an index-only inner query whose reference property supplies the outer documents' ids. Pages by a range on that property. Protocol 14 |
Clients: the Rust SDK (CompositeDocuments, ChainedDocuments, DocumentRankedEntries, DocumentHavingEntries) and wasm-sdk/js-evo-sdk (documents.composite, chained, ranked, having, each with a WithProof form).
2.6 Contract Queries
| Query | Purpose |
|---|---|
getDataContractsByRange |
Lists all contracts in id order, up to 100 per page, with a cursor and an ids-only mode |
getDataContractsLatestVersions |
Current version of up to 100 contracts, optionally with the contracts. From protocol 14 the proof covers a stored version item instead of whole contracts |
getContractGroupInfo, getContractGroupMembers, getContractGroupsForContract |
Read contract groups (protocol 14) |
All are provable. 5.0 clients accept only GroveDB V1 proof envelopes, which networks have served since protocol version 12.
3. Fees, Tokens and Contested Names
Contracts can now earn credits from their documents, contract owners can pay the gas of token-paid actions, tokens gain three features, and contested names and votes cost less. All of it applies from protocol version 14 unless marked.
3.1 Document Action Fees and Fee Pots
A document type may declare actionFees: a credit fee, on top of gas, for any of create, replace, delete, transfer, update_price, purchase. Each fee has an owner part and a moderators part (which needs contract moderation). "fixed" pricing charges the amounts as written; "feeMultiplier" (the default) scales them by the epoch's fee multiplier (amount × permille / 1000). The fees of an existing document type are fixed.
- Agreement: version 2 of the document base transition carries
$actionFeeAgreement, the amounts the signer saw plus, for multiplier pricing, the known multiplier and a tolerance in percent. A missing agreement (40132), other amounts or pricing (40133), or a multiplier above the tolerance (40134) is a paid refusal: the nonce is bumped and no action fee is charged. - Payment: whoever pays the gas pays the fee, only for an action that executes; the contract owner never pays the
ownerpart. The fee is not gas: fee pools and proposers get none of it. - Pots: an owner pot and a moderators pot per contract, stored as sum items covered by the per-block credit total check.
ContractFeeClaim(state transition type 25) pays each pot out at most once per epoch: the owner pot to the contract owner, the moderators pot in equal shares to the moderation team (a seated elected team uses its charter's split). A claim records its epoch, block time and claimant; refusals are 41111 (claimed this epoch), 41112 (nothing to pay) and 41113 (not a recipient). The provedgetContractFeePotsquery reads both pots; js-evo-sdk addscontracts.feePotsandcontracts.claimFees.
3.2 Token Costs and Gas Sponsorship
| Change | Behaviour |
|---|---|
tokenCost.gasFeesPaidBy |
Accepted since protocol version 9, now acted on. The cost offers document owner, contract owner or prefer contract owner; $tokenPaymentInfo asks. Unoffered requests are refused (40129); a batch has one payer (40130). If the contract owner cannot cover the gas and its action fees, an insisting batch is refused unpaid (40222) and a preferring one falls back to the signer. Storage refunds still go to the document owner. |
tokenCost.optional |
A transition may omit $tokenPaymentInfo and pay gas in credits, with no token charged. |
| Sponsored fee increase | The sponsor pays the fee without user_fee_increase; the signer pays the increase. |
| Payment policy | A paused token refuses document payments (40711). Paying a frozen contract owner is refused (40702) only under allowTransferToFrozenBalance: false. |
3.3 Tokens
| Feature | Detail |
|---|---|
| Non-transferable tokens | transferable: false (token configuration format 1, fixed at creation). TokenTransfer is refused (40726); mint, claim, purchase, burn, freeze and pause still work. Document costs in it must burn it (10280); no shielded pool (10279). |
| Once-per-identity distribution | oncePerIdentityDistribution: { amount }: each identity claims once (distribution type 2; repeat is 40722). 0.1 Dash registration surcharge. |
| Token shielded pools | hasShieldedPool: true (format 1, immutable) gives the token its own Orchard pool. Seven batch token transitions (shield, unshield, shielded transfer, mint, burn, claim and direct purchase to or from the pool) and three identity-less transitions (types 26 to 28) that pay their fee from the credit pool. Freeze, unfreeze and destroy-frozen-funds rules must be disabled (10278). The six shielded queries take an optional token_id. |
| Supply and distributions | Tokens added by a contract update get distribution storage and their base supply. Mints and direct purchases stop at an i64::MAX total supply (40705). Distribution math uses a pinned pure-Rust libm, identical on every architecture. An evonode participation claim reads at most 100 epochs (or one longer cycle). |
3.4 Contested Names and Masternode Votes
| Protocol version 13 | Protocol version 14 | |
|---|---|---|
| Contest fund (DPNS and others) | 0.2 Dash | 0.1 Dash |
| Vote cost, taken from the fund | 0.0001 Dash | 0.00002 Dash (80% less) |
| Fund to join | flat | doubles at 250 contenders and every 50 more (DPNS: 3,276.8 Dash for the 951st to 1,000th) |
| Prefunded voting balance | exactly the fund | the most it will pay; it is charged the fund to join |
| Tie | latest contender | earliest (creation time, block height, core height, document id) |
Also from protocol version 14: at most 1,000 contenders per contest (40141), all tallied at the end; a vote for an identity must name a contender (40307); resolution: 1 contests have no Lock choice and always have a winner (moderation elections use them, with a 0.5 Dash fund). At every protocol version, contested documents are accepted before epoch 4, which only affects new networks.
3.5 Storage Fee Accounting
- Storage paid by documents of a
ttltype goes to the epochs they live in (at most one era), through new lifetime pools, not the 50-era distribution. - A storage refund is taken back from the epoch pools it was priced for; the total is unchanged.
- Credits repaying an identity's fee debt go to the current epoch's processing fee pool.
- A batch merges its writes to one balance or fee pot into one net write.
4. Identity Keys, Contract Groups and App Connect
Protocol version 14 lets an identity give an app a key that acts only on chosen contracts, spends only up to a budget and stops at a set time. Contract groups name a family of contracts, and a new system contract carries the wallet-to-app login handshake.
4.1 Contract-Bound Authentication Keys
Before protocol 14 only ENCRYPTION and DECRYPTION keys could carry contract bounds. Now an AUTHENTICATION key below MASTER can be bound too:
contractBounds |
The key may sign |
|---|---|
singleContract { id } |
document and token operations on that contract |
documentType { id, documentTypeName } |
document operations of that type |
contractGroup { id } (new) |
operations on any contract, document type or token in the group |
A bound key signs only Batch transitions. A batch member outside the bounds is a paid failure.
4.2 Key Budgets and Expiry
Key format IdentityPublicKey V1 adds two optional fields, totalBudget (credits) and expiresAt (block time in milliseconds), allowed only on AUTHENTICATION keys below MASTER. Keys without limits stay V0.
- Budget. Credits moved out of the identity (a document purchase, a prefunded voting balance), the storage fee, fees priced up front and the user fee increase must fit in what is left. Only the metered processing fee may overshoot. Refunds never add to a budget. A spent key is refused.
- Expiry. The key signs until the block time reaches
expiresAt. IdentityKeyLimitsUpdate(type 23) raises a key's budget or moves its expiry later, never the reverse: to take a key back, disable it. It is signed by a MASTER key, or a CRITICAL key without limits or bounds.getIdentityKeysRemainingBudgetsreturns the remaining budget of up to 100 keys of one identity, with an optional proof.
IdentityCreateFromShieldedPool refuses limited and group-bound keys; add them with an identity update. The Rust, JavaScript, Swift and Kotlin SDKs and the platform wallet support limited keys, their update and the query.
4.3 Contract Groups
A contract group is an identity-owned set of contracts, document types and tokens, such as an app's v1 and v2 contracts and its token contract.
DataContractCreateversion 1 addscontractGroup(registers a group with optional name, description and admins) andcontractGroupMemberships. The group id derives from the owner and the identity nonce, so one transition can register a group and enrol its own contract.- A contract joins a group only in its own create transition, signed by the group's owner or an admin. Memberships are append-only.
- Limits: 16 memberships per contract, 16 admins, 64-character names, 256-character descriptions.
- Provable queries:
getContractGroupInfo,getContractGroupMembers(pages of at most 100) andgetContractGroupsForContract, also in js-evo-sdk assdk.contractGroups.
4.4 App Connect
The App Connect system contract (H8F9mP1BM55TE1ShsxPZHzhyinaMdY9bMmP85mkDhcJJ) is registered when protocol 14 activates. Its index-only document type loginKeyResponse holds:
| Property | Size | Meaning |
|---|---|---|
appEphemeralPubKeyHash |
20 bytes | hash160 of the app's request key |
walletEphemeralPubKey |
33 bytes | the wallet's key for the shared secret |
encryptedPayload |
60 to 572 bytes | 1 to 17 granted private keys, encrypted to the app |
After the user approves, the wallet registers keys for the app (typically bound to its contracts, with a budget and an expiry), waits for them to confirm and publishes the response, keyed by request hash and identity. The app decrypts the keys and checks they are live. The Swift example app can also pass a bounded login key to a browser over Bluetooth.
4.5 Other Identity Changes (protocol 14)
- A signature by a BLS12_381 identity key must verify.
- An
IdentityCreatewhose identity id does not match its asset lock, or anIdentityCreateorIdentityCreateFromAddresseswith a failed key proof of possession, is refused without a fee, leaving the asset lock or inputs unspent. - A hash key's data (ECDSA_HASH160, BIP13_SCRIPT_HASH, EDDSA_25519_HASH160) must be 20 bytes.
- DashPay v2 (DIP-33): profiles can publish
corePaymentAddressandplatformPaymentAddress(type byte0x00P2PKH or0x01P2SH, then a 20-byte hash) and a 43-byte OrchardshieldedAddress.
5. Moderation
Platform 5.0 lets a data contract bar identities and take down content through consensus, using moderators it appoints or a team elected by masternodes and evonodes. All of it is protocol version 14 behaviour.
5.1 Declaring Moderation
A contract declares moderation in its config: the lists it keeps (banlist, suspensions, warnings) and who moderates (contractOwner, appointedModerators with up to 16 existing identities, or elected). The lists are fixed at creation; an update may only change appointed moderators. The owner and appointed moderators cannot be listed, nor their documents deleted by moderation.
5.2 The Moderation Transition
The new ContractUserModeration transition (type 24) carries one action:
| Action | Effect |
|---|---|
ban / unban |
Bars an identity until unbanned; replaces a suspension |
suspend / unsuspend |
Bars an identity until a block time |
warn / clearWarnings |
Records a warning, up to 16 per identity; bars nothing |
deleteDocument / restoreDocument |
Removes or restores a document (5.3) |
changeDocumentFields |
Writes moderator-only fields (5.3) |
deleteSettledDocument / approveTeamAction |
Team deletion by approval (5.5) |
Entries and deletions store a reason: up to 1,024 bytes of text and 16 cited documents. A barred identity's document transitions on the contract are refused, paid, except deletions and replaces that meet the type's new retractedWhen condition, so undeletable documents can still be retracted. It cannot receive transfers or sell documents either. Token transitions are not affected.
5.3 Deleting, Restoring and Annotating Documents
Document types opt in with moderatorAbilities, fixed with the type:
| Key | Meaning |
|---|---|
delete |
Moderators may delete the type's documents |
deleteWithin |
Seconds after $updatedAt (else $createdAt) in which one moderator may delete; after that the document is settled |
deleteKeepsRecord |
Leave a removal record (default true) |
deleteKeepsFields |
Values kept public in the record |
deleteRefundsOwner |
Refund the owner's storage (default false) |
changeFields |
Properties only moderators write |
The removal record (owner, moderator, reason, block time and a double SHA-256 of the document) is paid by the moderator and never deleted. Within 7 days of a removal a moderator may restore the document by submitting it unchanged: it must match the hash and still pass the type's unique indexes and total-based propertyConstraints. A refersTo: moderatedDocument reference resolves to the record once its target is removed.
changeDocumentFields sets or removes changeFields properties, which an owner who is not a moderator cannot write. It raises $revision but not $updatedAt, so the deletion window does not reopen. The new system properties $moderatedAt and $moderatedBy record the last moderator write.
5.4 Elected Moderation Teams
An elected declaration is frozen at creation: join and vote windows (default one week, at most four weeks, at least one day on mainnet), seatContestable (challenges are not part of 5.0), an electionDelay, maxAddedModerators (0 to 15), the moderated document types with their abilities (ban, suspend, warn, deleteDocuments, changeDocumentFields), ownerProtected (shields the owner from the team), and an interim: contractOwner, appointedModerators, noModeration, or notYetUsable, which refuses the moderated types until a team is seated.
Teams apply through the new moderation charters system contract: reason documents, a leader's submittedCharter (its reasons, a moderatorsShare of the declared moderator fees and a rewardSplit), encrypted joinRequests, and an electedCharter naming up to 15 members who asked to join. After the target's election delay, an electedCharter opens or joins a contest run on the target's windows, each application prefunding 0.5 Dash. Masternodes and evonodes vote with no Lock choice; ties go to the earliest contender, and a sole contender wins at the end of the join window. In protocol version 14 a filled seat is not replaced.
Once seated, only the team moderates, and its members are protected: the leader and the elected members, less removedModerators, plus addedModerators. Each acts alone with the declared abilities, and each ban, suspension, warning, deletion or field change must cite a reason the proposal lists.
5.5 Settled Deletions, Rewards and Queries
moderatorAbilities.deleteSettled: { leader, approvals, approversPredateDocument } lets a seated team delete a settled document together: a member proposes, others approve, and the approval that meets the rule deletes it. An approval is refused once the document has changed. When more than one approval is needed, members the leader added count by default only for documents newer than their addition. A team deletion cannot be restored.
A member claims the moderators pot for the team once per epoch with ContractFeeClaim (type 25). The rewardSplit divides it into a leader share, an equal share and an action share, the last by each member's bans, suspensions, warnings and deletions since the last payout. A change of the team pays out the pot first.
New proved queries: getContractModerationStatus, getContractModerationEntries, getContractDocumentRemovals, getContractTeamActions, getContractTeamActionSigners, getContractModerationActionCounts and getContractFeePots.
6. Withdrawals, Shielded Pool and Core v24
Protocol version 14 ties the withdrawal limit to Platform's balance and to Core's own credit pool, connects identity balances to the shielded pool, and adds support for Dash Core v24.
6.1 Daily Withdrawal Limit (protocol 14)
The flat 2000 Dash per 24 hours is replaced:
- The base is 15% of the total credits Platform held a day earlier (at the latest block at least 24 hours old), never below one maximal withdrawal (500 Dash), with no fixed cap.
- Credits that entered Platform after that snapshot (asset locks, epoch Core block rewards) are added, so the limit counts net outflow: a deposit and the withdrawal it funds cancel out.
- For the first day after activation, the flat 2000 Dash still applies.
6.2 Core-Anchored Limit (protocol 14)
Withdrawals are pooled only up to the smaller of the daily limit and a stricter copy of Core v24's net unlock rule:
| Core v24 | Platform | |
|---|---|---|
| Allowed drop of the credit pool | 20% of its balance one window ago | 15% of the highest balance among the window starts Core may use |
| Floor | 2000 Dash | 1500 Dash |
| Window | 576 blocks (100 on regtest) | the same |
Platform also subtracts every withdrawal queued or broadcast and not yet completed. Drive reads the credit pool balance from the coinbase of each chain-locked Core block with getspecialtxes, at most 32 Core blocks per Platform block.
6.3 Withdrawal Processing
- Core fee (protocol 14). The asset unlock pays out the amount minus the Core fee, instead of taking the fee from the credit pool on top. Identity, address and shielded withdrawals must cover the 1000-duff minimum plus that fee, and the fee rate is capped at 6,765 duffs per byte.
- FAILED status (protocol 14). Withdrawals contract v2 adds the terminal status
5 - Failed. An expired withdrawal below Core's dust threshold for its output (546 duffs for P2PKH) is marked FAILED instead of being re-signed every 48 Core blocks. Its credits stay in Core's credit pool. - Faster signing. When a block queues a withdrawal, Drive asks Tenderdash 1.8 for the next block at once, instead of waiting up to 3 minutes on an idle chain.
6.4 Shielded Pool and Identities (protocol 14)
| Type | ID | Description |
|---|---|---|
| ShieldFromIdentity | 21 | Identity balance into the pool, with an outputs-only Orchard bundle, signed by a CRITICAL TRANSFER key. The identity pays metered fees plus the shielded verification fee |
| IdentityTopUpFromShieldedPool | 22 | Spends notes and credits an existing identity with topUpAmount minus a flat pool-paid fee. Identity and amount are bound into the Orchard sighash |
The Rust SDK and the platform wallet build both.
- Fees rebalanced. The proof verification fee drops from 100,000,000 to 40,000,000 credits per bundle, the storage allowance rises from 344 to 550 bytes per action, and the per-action processing fee stays 22,000,000. A 2-action bundle's minimum fee goes from 162,851,200 to 114,140,000 credits.
- Bound bundles. Outputs-only bundles bind their kind and funding source (input addresses, identity or asset lock) into the sighash, so a bundle is valid only in the transition it was built for.
ShieldFromAssetLockmoves to transition version 1. - Nullifiers.
Shield,ShieldFromAssetLockandShieldFromIdentityrecord the nullifier each action reveals and refuse a repeated one, as spends already did.
6.5 Dash Core v24
- With rust-dashcore v0.45.0, DAPI, the SDKs and the wallet decode Core v24 blocks and transactions (coinbase version 4, version 3 ProTx). Drive starts on Core v24, reading deployments with
getdeploymentinfo. The wallet builds version 3 ProUpServTx. - Masternode identities (protocol 14). Core v24 lists shared masternodes, with no owner, payout or collateral address, and masternodes with a
payoutslist. Without an owner address a masternode gets voter and operator identities only. An owner with a payout address or a single P2PKH payout gets the same identity as before (TRANSFER key 0, OWNER key 1); other payout lists get only the OWNER key. A change to a split, empty or unsupported list disables the TRANSFER keys, keeping the OWNER key and balance. - Platform ports (protocol 14). Drive reads evonode platform ports from Core v24's nested
addressesfirst, then the legacy fields. - Protocol 14 must be active on a network before Dash Core activates v24 there.
7. Additional Improvements
7.1 Protocol Version 14
Platform 5.0 activates protocol version 14, which gates every consensus change listed above behind one version boundary. Its first block runs a one-time migration:
- It rewrites the index keys of unsigned integer properties so they sort as their values do.
- It stores a version item beside every contract.
- It registers the app-connect and moderation charters system contracts.
- It updates the DashPay, withdrawals and token history contracts.
- It creates the new trees for contract groups, once-per-identity distributions, fee pots, token shielded pools, document time to live and withdrawal limits.
- It adds the nullifier carried by every note already in the shielded credit pool to the nullifier set.
7.2 SDK and Platform Wallet
- JS/WASM SDK (
js-evo-sdk):- Composite and chained document queries, typed arrays,
propertyConstraintsdiscovery and pre-checks, key limits and action fee agreements. - Contracts persisted and reused across SDK instances.
- Composite and chained document queries, typed arrays,
- Rust SDK:
- Verifies proofs signed at older or newer protocol versions.
- Refuses GroveDB V0 proof envelopes at every protocol version.
- No longer bans healthy nodes for requests every node refuses.
- The non-unique identity lookup is versioned, so 4.1 clients keep working.
- Swift SDK: off-main-thread wallet APIs, frozen SwiftData schemas for App Store builds, typed arrays and
propertyConstraintsin the iOS example app, and log exports with diagnostics. - Kotlin SDK: DashPay invitations, a reworked keystore, wallet builder controls and parity with the Swift SDK on the new protocol features.
- Platform Wallet:
- An embeddable SQLite storage backend that restores without the seed.
- DashPay payment history.
- Pooled spending across BIP44, BIP32 and DashPay accounts.
- Masternode tools: track masternodes, claim credits with the owner or payout key, unban through a ProUpServTx.
- A DPNS username marketplace, message signing, and CoinJoin funding for the shielded pool.
7.3 Hardening
- Block agreement across extra consensus rounds: vote extensions are checked against the round they belong to, and a block accepted in an earlier round is finalized correctly.
- Contested vote polls resolve reliably. Every contender is tallied, and masternode votes are checked the same way in
check_txas in a block. - Stricter decoding: trailing bytes are refused, untrusted length prefixes are bounded, and stored group actions decode without the proof budget.
- Shielding transitions record and check their nullifiers, BLS12_381 identity-key signatures must verify, and storage refunds are taken back from the epochs they were priced for.
- Fee estimates size count and sum trees correctly, and a sponsored batch's fee increase is charged to its signer.
- A new node syncs mainnet history without the crash-restarts it used to hit at heights 32,326 to 32,329.
- Drive no longer rewrites the whole platform state every block, and batch deletes are linear.
- Storage moves to GroveDB 6.1.1, and dependencies received security updates.
7.4 Dashmate
- Tenderdash 1.8, followed through the
1.8image tag so patch releases arrive without a dashmate release. - An optional Tor sidecar lets Core reach onion peers and publish an onion service.
dashmate updatechecks the gateway certificate, anddoctorreports why a renewal failed.- Core's RPC whitelist for Drive gains
getspecialtxesandgetdeploymentinfo. - Drive and rs-dapi images follow the release line (
dashpay/drive:5) unless the operator chose an image.
7.5 Test Coverage
36 test PRs and 68 CI PRs were merged during this cycle. They add:
- strategy tests for vote extension rounds, protocol upgrades, credit pool backfill and process-proposal collisions;
- request-error suites for queries;
- regression suites for operation proofs across protocol versions.
The npm and Kotlin release jobs now run on disposable runners.
Upgrading
Evonode operators
All evonodes must upgrade. A node still running 4.1.x stops when the network activates protocol version 14.
dashmate stop # stops the whole node, Core included
npm install -g dashmate # or install the package for your system from the assets below
dashmate update
dashmate startCore must restart for this upgrade. Do not use dashmate restart --platform: it leaves Core running. Drive 5.0 reads Core's credit pool balance (getspecialtxes), which Core only allows once it has restarted with the updated RPC whitelist. Drive refuses to start until then.
dashmate migrates existing configs automatically. Drive and rs-dapi move to the 5.x image line, Tenderdash moves to 1.8, and Core's RPC whitelist for Drive gains the methods it needs.
Protocol version 14 activation
- Evonodes signal protocol version 14 by proposing blocks with 5.0.
- At each epoch change, Platform counts the evonodes that proposed on 5.0 during the epoch that ended. Once that reaches 67% of active evonodes, protocol version 14 is scheduled for the next epoch change. A mainnet epoch lasts about 9 days.
- After protocol version 14 is scheduled, do not go back to 4.1.x.
Dash Core v24
Protocol version 14 must be active on a network before Dash Core activates v24 there. Earlier protocol versions cannot process the masternode list Core v24 produces (section 6.5).
App developers
Update to the 5.0 SDKs to use the new features once protocol version 14 is active. Several SDK APIs changed; see the changelog for breaking changes.
What's Changed
Features
Data Contracts & Documents
- feat(platform)!: reference validation for documents (refersTo) by @lklimek in #2993
- feat(platform)!: permanent document references (refersTo permanentDocument) by @QuantumExplorer in #4390
- feat(platform)!: identity public key references (refersTo identityPublicKey) by @QuantumExplorer in #4397
- feat(platform)!: required document fields via contract updates (requiredSince) by @QuantumExplorer in #4400
- feat(dpp)!: refersTo propertyAgreement binds referring and referenced document properties by @QuantumExplorer in #4505
- feat(platform): propertyAgreement over absent properties by @QuantumExplorer in #4524
- feat(dpp): immutable properties on mutable document types by @QuantumExplorer in #4815
- feat(dpp)!: propertyAgreement on $ownerId and $creatorId: referenced side and writer gate by @QuantumExplorer in #4816
- feat(wasm-dpp2): expose immutable document properties to JavaScript by @QuantumExplorer in #4817
- feat(sdk): show and lock immutable document properties in the mobile example apps by @QuantumExplorer in #4820
- feat(platform)!: document ids commit to the identity contract nonce by @QuantumExplorer in #4859
- feat(platform)!: references to deletable documents (refersTo deletableDocument) by @QuantumExplorer in #4860
- feat(platform)!: contract references may require a minimum age of, and time since the last update to, the referenced contract by @QuantumExplorer in #4913
- feat(platform)!: contract references may require the referenced contract's owner relation and config flags by @QuantumExplorer in #4915
- feat(platform)!: key references on the writer's own identity (PV14) by @QuantumExplorer in #4916
- feat(platform)!: distinctFrom on identifier properties (PV14) by @QuantumExplorer in #4917
- feat(platform)!: keyRequirements on identity key references (PV14) by @QuantumExplorer in #4918
- feat(platform)!: encryptedFor envelope declaration on byte properties (PV14) by @QuantumExplorer in #4919
- feat(dpp)!: typed scalar arrays in document schemas (PV14) by @QuantumExplorer in #4922
- feat(dpp)!: encode typed array elements as their scalar property type (PV14) by @QuantumExplorer in #4923
- feat(sdk): typed arrays in the Swift SDK and both mobile example apps (PV14) by @QuantumExplorer in #4926
- feat(platform)!: refersTo on typed array elements (PV14) by @QuantumExplorer in #4928
- feat(platform)!: document references resolved through a unique index (PV14) by @QuantumExplorer in #4930
- feat(platform)!: listElement references into a list of a referenced document (PV14) by @QuantumExplorer in #4940
- feat(platform)!: ownerRefersTo and creatorRefersTo, references on the document's writer and creator (PV14) by @QuantumExplorer in #4941
- feat(platform)!: anyOf and allOf reference expressions (PV14) by @QuantumExplorer in #4942
- feat(platform)!: maxBytes, a UTF-8 byte cap on document strings (PV14) by @QuantumExplorer in #4957
- feat(platform)!: propertyConstraints, integer rules between document properties (PV14) by @QuantumExplorer in #4962
- feat(platform)!: documents with a time to live, deleted by the platform (PV14) by @QuantumExplorer in #5007
- feat(platform)!: pay document ttl storage fees to the epochs the documents live in (PV14) by @QuantumExplorer in #5033
- feat(platform)!: anyOf, allOf and not in propertyConstraints rules (PV14) by @QuantumExplorer in #5036
- feat(platform)!: present and absent tests in propertyConstraints rules (PV14) by @QuantumExplorer in #5037
- feat(platform)!: in, value membership in propertyConstraints rules (PV14) by @QuantumExplorer in #5038
- feat(platform)!: boolean operands in propertyConstraints rules (PV14) by @QuantumExplorer in #5040
- feat(platform)!: a refersTo may find its document by a hash the document reveals (PV14) by @QuantumExplorer in #5041
- feat(platform)!: string equality for enums in propertyConstraints rules (PV14) by @QuantumExplorer in #5042
- feat(platform)!: compare two string properties in propertyConstraints rules (PV14) by @QuantumExplorer in #5045
- feat(platform)!: string ifAbsent defaults in propertyConstraints rules (PV14) by @QuantumExplorer in #5046
- feat(platform)!: identifier comparisons in propertyConstraints rules (PV14) by @QuantumExplorer in #5047
- feat(platform)!: $ownerId comparisons in propertyConstraints rules (PV14) by @QuantumExplorer in #5048
- feat(sdk): propertyConstraints discovery and pre-check in the JS SDK by @QuantumExplorer in #5051
- feat(sdk): propertyConstraints rules and pre-check in the Swift SDK and iOS example app by @QuantumExplorer in #5064
- feat(sdk): propertyConstraints rules and pre-check in the Kotlin SDK and Android example app by @QuantumExplorer in #5066
- feat(platform)!: string length, byte length and array count operands in propertyConstraints rules (PV14) by @QuantumExplorer in #5071
- feat(platform)!: creation, update and transfer times and heights in propertyConstraints rules (PV14) by @QuantumExplorer in #5078
- feat(platform)!: contains in propertyConstraints rules (PV14) by @QuantumExplorer in #5083
- feat(platform)!: startsWith and endsWith in propertyConstraints rules (PV14) by @QuantumExplorer in #5085
- feat(kotlin-sdk)!: new propertyConstraints read kinds and system reads in the Kotlin SDK and Android example app by @QuantumExplorer in #5097
- feat(swift-sdk)!: new propertyConstraints read kinds and system reads in the Swift SDK and iOS example app by @QuantumExplorer in #5098
- feat(platform)!: generatedFrom, string properties the platform generates with a system function (PV14) by @QuantumExplorer in #5099
- feat(platform)!: ifThen, ifThenElse, notIn, min, max and abs in propertyConstraints rules (PV14) by @QuantumExplorer in #5100
- feat(platform)!: countOf and sumOf totals from count and sum trees in propertyConstraints rules (PV14) by @QuantumExplorer in #5109
- feat(sdk)!: countOf and sumOf totals in the rule descriptors of the JS, Swift and Kotlin SDKs by @QuantumExplorer in #5121
- feat(dpp)!: skipIfAbsent at any position, true or an array, on every document type (PV14) by @QuantumExplorer in #5162
- feat(dpp)!: refersTo finds a document with findBy and checks it with where by @QuantumExplorer in #5197
- feat(platform)!: immutable properties frozen under a condition (PV14) by @QuantumExplorer in #5217
- feat(platform)!: documents only a consume deletes (canBeDeleted "onlyWhenConsumed", PV14) by @QuantumExplorer in #5239
- feat(platform)!: bound the summed values of a document type with a ttl (PV14) by @QuantumExplorer in #5316
- feat(platform)!: rules that gate the owner's delete (deleteConstraints, PV14) by @QuantumExplorer in #5319
- feat(dpp)!: count how many of a group of properties a document sets (countPresent, PV14) by @QuantumExplorer in #5332
- feat(platform)!: let property constraint rules read the bytes of byte arrays (PV14) by @QuantumExplorer in #5336
- feat(swift-sdk): decode the "bytes" propertyConstraints read kind by @QuantumExplorer in #5339
- feat(dpp)!: add identifier and bytes property type shorthands (PV14) by @QuantumExplorer in #5355
- feat(sdk): read the identifier and bytes property type shorthands in long form on iOS and Android by @QuantumExplorer in #5358
- feat(dpp)!: consume and minimumAgeBlocks on any reference judged on the create alone by @QuantumExplorer in #5365
- feat(dpp)!: find a referenced document by a string or byte array property's value by @QuantumExplorer in #5367
- feat(platform)!: rules that read the referenced document (PV14) by @QuantumExplorer in #5369
- feat(dpp)!: choose the first valid commitment to the same values (chooseFirst) by @QuantumExplorer in #5371
- feat(platform)!: propertyConstraints rules read the stored document ($old., $revision, PV14) by @QuantumExplorer in #5373
- feat(platform)!: compare typed arrays in refersTo where entries (PV14) by @QuantumExplorer in #5388
Index-Only Types & Advanced Queries
- feat!: add time-range indexes for trending/leaderboard queries by @QuantumExplorer in #3740
- feat: ranked aggregate indexes with provable top-K queries (protocol v14) by @QuantumExplorer in #4266
- feat(drive): boolean HAVING range queries on ranked index axes by @QuantumExplorer in #4384
- feat(drive)!: multiple IN clauses on consecutive index properties in document queries by @QuantumExplorer in #4391
- feat(drive): per-prefix ranked aggregates on compound indexes by @QuantumExplorer in #4393
- feat(drive): support IN over pinned prefix properties in ranked and having-range queries by @QuantumExplorer in #4401
- feat: expose protocol v14 ranked queries and document references to JavaScript by @QuantumExplorer in #4450
- feat(dpp)!: add indexOnly document types with terminal index keys by @QuantumExplorer in #4491
- feat(drive)!: indexOnly storage layout — index entries as the rows by @QuantumExplorer in #4492
- feat(drive)!: indexOnly read surface — synthesize documents from index positions by @QuantumExplorer in #4494
- feat(sdk): indexOnly delete-by-values through the SDKs; book chapter by @QuantumExplorer in #4495
- feat(dpp)!: indexOnly delete-by-values as its own transition kind by @QuantumExplorer in #4497
- feat(drive): indexOnly terminal-property where clauses and keyset pagination by @QuantumExplorer in #4499
- feat(drive)!: sum axes on indexOnly indexes via ItemWithSumItem terminals by @QuantumExplorer in #4506
- feat(drive)!: timeRange buckets on indexOnly indexes by @QuantumExplorer in #4508
- feat(drive)!: preallocated indexOnly index trees created at referenced-document insert by @QuantumExplorer in #4509
- feat(dpp): skipIfAbsent index keyword for indexOnly document types by @QuantumExplorer in #4522
- feat(drive): skip absent-property indexes on indexOnly writes by @QuantumExplorer in #4523
- feat(dpp): rankedCountable at-form for prefix-level count ranking by @QuantumExplorer in #4531
- feat(drive): storage layout and maintenance for prefix-level ranked count indexes by @QuantumExplorer in #4533
- feat(drive): serve ranked and having-range queries at a prefix ranking level by @QuantumExplorer in #4535
- feat(drive): serve prefix-pinned count queries off the terminal aggregate by @QuantumExplorer in #4537
- feat(drive): admit plain sibling indexes beside a prefix-ranked chain via NonCounted branches by @PastaPastaPasta in #4543
- feat(drive): chained document queries — provable semi-join (posts I liked) by @QuantumExplorer in #4547
- feat(dapi): chained document queries on the getDocuments V1 wire by @QuantumExplorer in #4549
- feat(sdk): chained document queries — ChainedDocuments fetch with composed proof verification by @QuantumExplorer in #4552
- feat(wasm-sdk): chained document queries with js-evo-sdk facade and suite coverage by @QuantumExplorer in #4567
- feat(dapi): typed IN_TIME_RANGE operand with BY_START historic window selection by @QuantumExplorer in #4574
- feat(drive): ranked windowed top-K — ranked indexes below timeRange buckets by @QuantumExplorer in #4578
- feat(drive): time-range index TTL — O(1) flat-drop drainage and ephemeral-bytes fees by @QuantumExplorer in #4581
- feat(drive): composite document queries: a page plus derived sub-queries under one merged proof by @QuantumExplorer in #4598
- feat(dapi): composite document queries on the getDocuments V1 wire by @QuantumExplorer in #4603
- feat(sdk)!: support composite queries through DocumentQuery by @QuantumExplorer in #4604
- feat(wasm-sdk): composite document queries on the JS surface by @QuantumExplorer in #4605
- feat(platform): add getDataContractsByRange paginated contract enumeration query by @QuantumExplorer in #4733
- feat(rs-sdk-ffi): expose getDataContractsByRange to Swift and Kotlin by @QuantumExplorer in #4734
- feat(platform): add getDataContractsLatestVersions query for cheap contract staleness checks by @QuantumExplorer in #4739
- feat(platform)!: prove data contract versions without the contracts via a PV14 version item by @QuantumExplorer in #4749
- feat(sdk): add an off-main data contract query by @romchornyi in #4775
- feat(platform)!: composite and flat indexOnly terminals with an entry payload by @QuantumExplorer in #4866
- feat(platform)!: integerRange index buckets an integer property into windows by @QuantumExplorer in #5170
- feat(platform)!: index a value of the document a reference points at (PV14) by @QuantumExplorer in #5216
- feat(platform)!: derived index properties read a removed document's kept fields (PV14) by @QuantumExplorer in #5223
- feat(platform)!: index entries that outlive a delete (outlivesDelete, PV14) by @QuantumExplorer in #5232
- feat(platform)!: summableOffCountIndex keeps one counter per group of another index (PV14) by @QuantumExplorer in #5250
- feat(platform)!: skipIfAbsent may skip on a derived index property (PV14) by @QuantumExplorer in #5318
- feat(platform)!: index the elements of typed arrays (PV14) by @QuantumExplorer in #5370
- feat(sdk): query the elements of typed arrays over the wire (PV14) by @QuantumExplorer in #5372
- feat(platform)!: let an indexOnly type index the elements of a typed array (PV14) by @QuantumExplorer in #5390
- feat(platform)!: key preallocated and summableOffCountIndex indexes through a typed-array where (PV14) by @QuantumExplorer in #5394
Fees, Tokens & Contested Names
- feat(sdk): masternodes-by-voting-key lookup (contested-username voting post-cutover) by @bfoss765 in #4258
- feat(swift-sdk): typed DPNS contested-name browsing for voters by @QuantumExplorer in #4328
- feat(sdk): expose the label each contender actually requested by @QuantumExplorer in #4331
- feat(platform)!: halve contested name fee in protocol 14 by @QuantumExplorer in #4634
- feat(platform)!: token shielded pools by @QuantumExplorer in #4760
- feat(platform)!: let the contract owner pay the gas of token-paid document actions by @QuantumExplorer in #4826
- feat(platform)!: once-per-identity token distribution by @QuantumExplorer in #4827
- feat(platform)!: optional document token costs paid in credits when the token payment is left out by @QuantumExplorer in #4828
- feat(sdk): once-per-identity token distribution in the mobile example apps by @QuantumExplorer in #4829
- feat(platform)!: document action fees paid to the contract owner and moderators, with a fee claim state transition by @QuantumExplorer in #4851
- feat(platform)!: record who claimed a contract fee pot and when, query the pots, and claim them from the wasm and JavaScript SDKs by @QuantumExplorer in #4856
- feat(platform)!: document transitions state the action fee they agree to pay by @QuantumExplorer in #4858
- feat(platform)!: contested indexes resolved without locking, ties to the earliest contender (moderation teams A1) by @QuantumExplorer in #4907
- feat(platform)!: masternode votes cost 80% less (PV14) by @QuantumExplorer in #4959
- feat(drive-abci)!: allow contested documents before epoch 4 by @QuantumExplorer in #4995
- feat(platform)!: a contender's fund doubles for every 50 contenders a contest holds past 250 (PV14) by @QuantumExplorer in #5034
- feat(sdk): let apps that build document creates by hand state the contest fund by @QuantumExplorer in #5163
- feat(sdk): let document writes state the action fee agreement by @PastaPastaPasta in #5169
- feat(platform)!: bound the summed values of a contested document type (PV14) by @QuantumExplorer in #5240
- feat(platform)!: non-transferable tokens (PV14) by @QuantumExplorer in #5353
Identity Keys, Contract Groups & App Connect
- feat(platform)!: allow contract-bound authentication keys by @QuantumExplorer in #4780
- feat(platform)!: add contract groups by @QuantumExplorer in #4791
- feat(platform): add the contract group queries by @QuantumExplorer in #4792
- feat(platform)!: allow authentication keys bound to a contract group by @QuantumExplorer in #4793
- feat(platform)!: allow authentication keys with a budget and an expiry by @QuantumExplorer in #4798
- feat(platform): add the getIdentityKeysRemainingBudgets query by @QuantumExplorer in #4802
- feat(platform)!: add the IdentityKeyLimitsUpdate state transition by @QuantumExplorer in #4807
- feat(sdk)!: key limits on every client: wasm-dpp2, platform-wallet, FFI, Kotlin and Swift by @QuantumExplorer in #4811
- feat(swift-example-app): share a bounded login key with a browser over Bluetooth by @QuantumExplorer in #4823
- feat(platform)!: add app-connect login response system contract by @QuantumExplorer in #4869
Moderation
- feat(platform)!: contract moderation with a banlist and a suspension list by @QuantumExplorer in #4830
- feat(platform)!: a reason on contract bans and suspensions by @QuantumExplorer in #4849
- feat(platform)!: moderators delete documents of the document types that allow it by @QuantumExplorer in #4857
- feat(platform)!: a window after a document's last modification for moderators to delete it by @QuantumExplorer in #4864
- feat(platform)!: a warning list for moderated contracts by @QuantumExplorer in #4872
- feat(platform)!: a moderation reason names the documents it is about by @QuantumExplorer in #4884
- feat(platform)!: restore moderator-deleted documents from a hashed removal record by @QuantumExplorer in #4885
- feat(platform)!: elected moderation team declaration with frozen election parameters and interim mode by @QuantumExplorer in #4886
- feat(platform)!: moderation charters system data contract by @QuantumExplorer in #4898
- feat(platform)!: contract references may require the referenced contract to declare elected moderation by @QuantumExplorer in #4909
- feat(platform)!: elected contracts declare their own election delay, read by the electionOpen reference requirement by @QuantumExplorer in #4914
- feat(platform)!: charter elections use the target contract's windows and a 0.5 Dash fund (PV14) by @QuantumExplorer in #4951
- feat(platform)!: elected moderation teams moderate from their stored charter by @QuantumExplorer in #4952
- feat(sdk): encryptedFor helpers and moderation charter readers by @QuantumExplorer in #4953
- feat(platform)!: deletable charter team changes and lookups on deletableDocument references (PV14) by @QuantumExplorer in #4967
- feat(platform)!: elected moderation declares whether its seat is contestable (PV14) by @QuantumExplorer in #4969
- feat(platform)!: moderation team reward split, action counters and reason check by @QuantumExplorer in #4971
- feat(platform)!: elected moderation windows may be 0 off mainnet, mainnet keeps one day (PV14) by @QuantumExplorer in #5108
- feat(dpp)!: moderator-only document fields and deletion record and refund options (PV14) by @QuantumExplorer in #5158
- feat(dpp)!: $moderatedAt and $moderatedBy record the last moderator's write (PV14) by @QuantumExplorer in #5161
- feat(dpp)!: refersTo moderatedDocument, a reference that outlives a moderator's removal (PV14) by @QuantumExplorer in #5214
- feat(platform)!: a seated moderation team deletes settled documents by approval (PV14) by @QuantumExplorer in #5215
- feat(dpp)!: moderator removal records keep the fields a type lists (PV14) by @QuantumExplorer in #5219
- feat(platform)!: preallocated indexes may be bound through moderatedDocument references (PV14) by @QuantumExplorer in #5229
- feat(platform): moderation reads: approval counts, action counts and team seats (PV14) by @QuantumExplorer in #5230
- feat(platform)!: let a banned or suspended author retract with a declared replace (PV14) by @QuantumExplorer in #5253
- feat(platform)!: only members added before a document approve its settled deletion (PV14) by @QuantumExplorer in #5260
Withdrawals, Shielded Pool & Core v24
- feat(platform-wallet): CoinJoin-drain asset-lock funding for the shielded pool by @QuantumExplorer in #4327
- feat: expose Platform-to-Shielded capacity preflight by @llbartekll in #4360
- feat(kotlin-sdk): coinjoin-drain shielded funding binding + typed asset-lock shortfall by @bfoss765 in #4361
- feat(drive)!: raise the daily withdrawal limit to 4000 Dash by @QuantumExplorer in #4452
- feat(drive)!: make the daily withdrawal limit 15% of the total credits held a day ago by @QuantumExplorer in #4457
- feat(dpp)!: rebalance the shielded fee constants for protocol 14 by @QuantumExplorer in #4467
- feat(platform-wallet): shield Platform credits to an external Orchard recipient by @QuantumExplorer in #4472
- feat(drive)!: count credit inflows against the daily withdrawal limit by @QuantumExplorer in #4486
- feat(platform)!: add ShieldFromIdentity state transition (identity balance to shielded pool) by @QuantumExplorer in #4708
- feat(platform)!: add IdentityTopUpFromShieldedPool state transition (shielded pool to identity) by @QuantumExplorer in #4711
- feat(drive-abci): ask Tenderdash for the next block right away when withdrawal work is queued by @QuantumExplorer in #4741
- feat(dpp)!: dashpay profile shielded address field by @QuantumExplorer in #4768
- feat(rs-dapi): refuse shielded broadcasts from addresses that keep sending invalid proofs by @QuantumExplorer in #5001
- feat(platform)!: support Core v24 masternode identities at protocol version 14 by @shumkov in #5227
- feat(drive-abci)!: resolve Core v24 platform ports at protocol version 14 by @shumkov in #5228
- feat(platform)!: withdrawals also fit a Core-anchored limit (PV14) by @QuantumExplorer in #5237
Platform Wallet
- feat(platform-wallet-storage): embeddable SQLite persistence backend with seedless rehydration by @Claudius-Maginificent in #3968
- feat(platform-wallet): registry-owned coordinator lifecycle with Rust-owned FFI callback contexts by @QuantumExplorer in #4268
- feat(platform-wallet): secp256k1 primitives, identity-update parsing, and scoped signing keys for DashConnect by @romchornyi in #4273
- feat(platform-wallet): add encrypted txMetadata document support by @QuantumExplorer in #4277
- feat(platform-wallet): reconstruct sent DashPay payments from tx history by @romchornyi in #4300
- feat(platform-wallet): classic Dash message signing (signMessage) over FFI, JNI, Kotlin, and Swift by @QuantumExplorer in #4319
- feat(platform-wallet): persist DashPay payment history through the persister callback by @QuantumExplorer in #4326
- feat(platform-wallet): pool BIP44 + BIP32 + DashPay receiving funds on the send path by @QuantumExplorer in #4329
- feat(platform-wallet): expose an invitation's prospective identity id by @romchornyi in #4332
- feat(platform-wallet): derive owner/voting provider keys Rust-side by @QuantumExplorer in #4338
- feat(platform-wallet): rebuild tracked asset locks after restore; honest scan-derived shielded history by @QuantumExplorer in #4342
- feat(platform-wallet): wallet-level DPNS username marketplace with FFI and Swift wrappers by @QuantumExplorer in #4348
- feat(platform-wallet): pool BIP44 + BIP32 + DashPay receiving funds on the asset-lock path by @bfoss765 in #4350
- feat(platform-wallet): own the DashPay startup ordering instead of each client by @romchornyi in #4359
- feat(platform-wallet): claim masternode credits with the owner or payout key by @QuantumExplorer in #4451
- feat(platform-wallet): locate and track masternodes independently of any wallet by @QuantumExplorer in #4465
- feat(platform-wallet): external recipient support for asset-lock address funding by @PastaPastaPasta in #4501
- feat(platform-wallet): unban a PoSe-banned masternode — ProUpServTx orchestration, FFI, Swift by @QuantumExplorer in #4507
- feat(platform-wallet): prepare a ProUpServTx without broadcasting it by @QuantumExplorer in #4512
- feat(platform-wallet): expose address funding fee estimate by @llbartekll in #4546
- feat(platform-wallet): let a Core build fund from only the inputs it was given by @romchornyi in #4548
- feat(platform-wallet): sweep changeset types, FFI seam, and persistence capability bits by @romchornyi in #4558
- feat(platform-wallet): report the balance a pooled build can actually spend by @romchornyi in #4582
- feat(platform-wallet): parse a state transition's kind and token-purchase intent by @romchornyi in #4584
SDK (JS / WASM / Rust)
- feat(sdk): expose OP_RETURN, output-order and change-to-VIN0 controls by @romchornyi in #4286
- feat(rs-sdk): own the masternode voting-key facts by @QuantumExplorer in #4340
- feat(sdk): add transport feature to dapi-grpc for types-only consumers by @PastaPastaPasta in #4344
- feat(sdk-ffi): expose the current epoch; fix getCurrentEpoch and the proposed-blocks range proof by @QuantumExplorer in #4453
- feat(sdk-ffi): ask one evonode for its DAPI status; expose the platform HTTP port by @QuantumExplorer in #4461
- feat(sdk): seed devnets at protocol version 14 and persist the learned version by @QuantumExplorer in #4735
- feat(wasm-sdk): persist fetched data contracts and seed the next SDK from them by @QuantumExplorer in #4744
- feat(wasm-sdk): let apps seed the contracts they already hold by @QuantumExplorer in #4746
- feat(sdk): carry consensus error codes through the wallet FFI by @QuantumExplorer in #4838
- feat(sdk)!: derive nonce-committed document ids in the JavaScript document create path by @PastaPastaPasta in #4868
- feat(sdk)!: DataContract.validateUpdate in @dashevo/wasm-dpp2 by @QuantumExplorer in #5140
- feat(sdk): persist the owner balance a document write's proof carries by @llbartekll in #5409
Swift SDK / iOS Example App
- feat(swift-sdk): expose watermark-freeze sync fault flag (syncFaultDetected) by @QuantumExplorer in #4320
- feat(swift-sdk): split build/broadcast with reservation release for BIP70-style deferred submission by @QuantumExplorer in #4322
- feat(swift-sdk): add async off-main wallet manager shutdown by @llbartekll in #4469
- feat(swift-sdk): add async off-main createWallet(mnemonic:) overload by @llbartekll in #4483
- feat(swift-sdk): add async off-main loadFromPersistor() overload by @llbartekll in #4487
- feat(swift-sdk): include critical Swift diagnostics in log exports by @llbartekll in #4544
- feat(swift-sdk): generate the frozen SwiftData schema models, and guard them with real stores by @shumkov in #4644
- feat(swift-sdk)!: freeze schemas only after App Store publication by @llbartekll in #4818
Kotlin SDK / Android Example App
- feat(kotlin-sdk)!: keystore rework — policy-alias split, layered key recovery, durable repair, structured signer errors (stacked on #4191) by @bfoss765 in #4183
- feat(kotlin-sdk): tx-label & asset-lock-kind DAO resolver queries by @bfoss765 in #4251
- feat(kotlin-sdk): expose core_wallet_next_receive_address / next_change_address (Swift parity) by @HashEngineering in #4260
- feat(kotlin-sdk): dashpay invitations — create, claim, reclaim, persistence (DIP-13) by @shumkov in #4284
- feat(kotlin-sdk): bind OP_RETURN, output-order and VIN0-change builder controls by @HashEngineering in #4288
- feat(kotlin-sdk): split build/broadcast with reservation release for BIP70-style deferred submission by @bfoss765 in #4308
- feat(kotlin-sdk): expose the drain strategy and the amount it delivers by @HashEngineering in #4324
- feat(kotlin-sdk): expose core_wallet_set_gap_limit to Kotlin (migrated-wallet address-window heal) by @bfoss765 in #4377
- feat(kotlin-sdk): bind the ordered wallet bring-up (startWalletSubsystems) over JNI by @HashEngineering in #4658
Drive & Drive-ABCI
- feat(platform): introduce protocol version 14 by @QuantumExplorer in #4267
- feat(dpp)!: dashpay profile payment addresses for core and platform by @QuantumExplorer in #4380
- feat(drive-abci): debug-only per-block phase timing by @PastaPastaPasta in #4573
- feat(drive-abci): store platform state masternodes and validator sets as one aux entry each by @QuantumExplorer in #4772
- feat(drive): describe the GroveDB structure as code by @QuantumExplorer in #4845
- feat(drive): describe the element flags of the GroveDB structure by @QuantumExplorer in #4848
- feat(drive): record the Merk shape of layers below a template by @QuantumExplorer in #4850
- feat(platform)!: a document batch proof carries the owner's credit balance by @QuantumExplorer in #4887
- feat(dpp): exact and untagged untrusted state transition decode via the derive's consumed byte count by @QuantumExplorer in #4931
- feat(drive): compute a document type's GroveDB layout for the SDKs by @QuantumExplorer in #5153
- feat(drive): compute what creating a document costs for the SDKs by @QuantumExplorer in #5159
Dashmate
- feat(dashmate)!: record whether a platform image was chosen instead of deriving it by @shumkov in #4239
- feat(dashmate)!: check the gateway certificate on update by @shumkov in #4440
- feat(dashmate): record why certificate renewal failed so doctor can name the cause by @shumkov in #4476
- feat(dashmate): run a Tor sidecar so Core reaches onion peers and publishes an onion service by @PastaPastaPasta in #4622
Other Features
- feat: document-throughput load-test tool by @shumkov in #4376
- feat: register funded identities via a ChainLock asset lock by @shumkov in #4399
- feat: add Value::same_scalar_data for comparing single values across variants by @QuantumExplorer in #5125
Bug Fixes
SDK (JS / WASM / Rust)
- fix(sdk): restore proved current-epoch fetch with two-step explicit-start query by @QuantumExplorer in #4231
- fix(sdk): point parity manifest at the renamed identity-resume test by @QuantumExplorer in #4304
- fix(rs-sdk-ffi): build the voter identifier from ProTxHash byte order by @QuantumExplorer in #4333
- fix(sdk): skip TLS-dead seed nodes + shielded-sync network diagnostics by @llbartekll in #4418
- fix(sdk): enforce the server's limit contract when lowering document queries by @PastaPastaPasta in #4434
- fix(sdk-ffi): carry the limit in the proposed-epoch-blocks range request by @QuantumExplorer in #4456
- fix(sdk): separate the deletion-resolution doc from the Returns list by @shumkov in #4498
- fix(wasm-sdk): seed the contract cache from contract fetches and share in-flight fetches by @QuantumExplorer in #4596
- fix(sdk)!: keep Keystore's unlocked-device gate from bricking wallets and signing on defective OEM builds by @HashEngineering in #4643
- fix(sdk)!: enforce a per-protocol-version minimum GroveDB proof envelope (V1 from v14) by @QuantumExplorer in #4701
- fix(wasm-sdk): keep the protocol-version store off wasm-bindgen imports natively by @QuantumExplorer in #4743
- fix(rs-sdk): resolve DPNS names whose identity record is not an Identifier value by @QuantumExplorer in #4769
- fix(sdk): retry DPNS broadcasts when owner identity is missing by @llbartekll in #4797
- fix(sdk): fetch and persist managed identity credit balances by @llbartekll in #4799
- fix(sdk): persist the contract bounds kind on Android and iOS by @QuantumExplorer in #4800
- fix(sdk): gate the address trunk-state proof on the GroveDB envelope floor by @QuantumExplorer in #4810
- fix(sdk): parse the $type map for the perpetual distribution recipient on iOS by @QuantumExplorer in #4824
- fix(sdk): parse change-control action takers from the rs-dpp $type map on iOS by @QuantumExplorer in #4825
- fix(wasm-dpp): pin the serialized contract transition length to the V2 config by @QuantumExplorer in #4883
- fix(rs-sdk-ffi)!: sanitize properties in dash_sdk_document_set_properties by @QuantumExplorer in #4927
- fix(sdk): don't panic in DapiClient::new on an empty address list by @PastaPastaPasta in #4964
- fix(sdk): bound each DAPI request attempt, including the response body by @llbartekll in #4973
- fix(sdk): keep the chosen DPNS name across wallet sync by @romchornyi in #4978
- fix(rs-sdk-ffi): stop probing google.com and testnet quorums on every SDK build by @QuantumExplorer in #5008
- fix(wasm-sdk): leave price tier validation to rs-dpp by @QuantumExplorer in #5058
- fix(wasm-sdk): keep StateTransitionResult.ownerBalance exact in JSON by @QuantumExplorer in #5059
- fix(sdk): consensus errors reach JS with their code by @QuantumExplorer in #5112
- fix(sdk): consensus errors reach Swift and Kotlin apps with their code by @QuantumExplorer in #5116
- fix(sdk): index-only document creates and deletes resolve once they land by @QuantumExplorer in #5136
- fix(sdk): masternodeVote takes the ProTxHash as an Identifier and returns the vote by @QuantumExplorer in #5138
- fix(sdk): accept vote poll end-date timestamps by @QuantumExplorer in #5139
- fix(sdk): run blocking Swift SDK Platform queries off the caller's actor by @romchornyi in #5146
- fix(wasm-sdk): fetch the moderated contract before verifying moderation proofs by @QuantumExplorer in #5213
- fix(sdk): refuse GroveDB V0 proof envelopes at every protocol version by @QuantumExplorer in #5294
- fix(sdk)!: fetch missing quorum keys instead of banning every node by @shumkov in #5313
- fix(sdk): stop banning nodes for requests every node refuses by @QuantumExplorer in #5334
- fix(sdk): bind voting proof queries to the default limit by @shumkov in #5356
- fix(sdk): return errors for unsupported proof modes by @shumkov in #5387
- fix(wasm-sdk): strip the default wasm URL from the sanitized glue by @PastaPastaPasta in #5389
- fix(wasm-sdk): cache verified contract updates without regressing versions by @shumkov in #5391
- fix(wasm-sdk): report state transition wait failures accurately by @shumkov in #5400
- fix(sdk): accept a contains pin in the ranked query type by @QuantumExplorer in #5402
- fix(wasm-sdk): accept Identifier instances in group queries by @shumkov in #5405
- fix(wallet-lib): keep @yarnpkg/pnpify out of runtime dependencies so npm can install dashmate by @shumkov in #5435
- fix(sdk): read contested DPNS names as the bare labels Drive returns by @QuantumExplorer in #5482
- fix(sdk): verify no-limit vote queries against the page Drive proves by @QuantumExplorer in #5483
- fix(sdk): verify no-limit proposer, distribution and group queries against the page Drive proves by @QuantumExplorer in #5485
- fix(sdk)!: version the non-unique identity lookup so 4.1 clients keep working by @lklimek in #5515
- fix(sdk): verify operation proofs signed by older and newer protocol versions by @shumkov in #5541
DPP (Dash Platform Protocol)
- fix(dpp): derive deterministic names for unnamed document type indexes by @QuantumExplorer in #4280
- fix(dpp): make document type index update validation name-order independent by @QuantumExplorer in #4291
- fix(dpp): stop hard-erroring on index-order-only contract updates by @QuantumExplorer in #4295
- fix(dpp): unbreak v4.2-dev — fmt gate and propertyAgreement compile breaks by @QuantumExplorer in #4515
- fix(dpp): surface identifier-typed document properties as base58 in JS by @QuantumExplorer in #4577
- fix(dpp): bound untrusted length prefixes on the proof-verification decode path by @PastaPastaPasta in #4629
- fix(dpp)!: deterministic token distribution math across architectures by @PastaPastaPasta in #4645
- fix(dpp)!: stop epoch-based perpetual distribution claims wrapping their cycle cap by @QuantumExplorer in #4747
- fix(dpp)!: weight evonode reward cycles by the epochs they span, not the step index by @QuantumExplorer in #4750
- fix(dpp)!: reject a zero epoch interval for perpetual distributions at registration by @QuantumExplorer in #4752
- fix(dpp): make the v3 meta-schema aggregate prerequisites sugar-aware by @PastaPastaPasta in #4809
- fix(dpp): refuse a document type schema that is not an object as an invalid contract structure again by @QuantumExplorer in #4870
- fix(dpp)!: typed array review fixes: hyphenated list paths, element constraints, untrusted lists, Swift refusal by @QuantumExplorer in #4924
- fix(dpp)!: contract updates may not change an integer property's width or signedness (PV14) by @QuantumExplorer in #4925
- fix(dpp)!: refuse lookup key sources inside a transient object (PV14) by @QuantumExplorer in #4943
- fix(dpp): refuse encryptedFor paths inside a transient object (PV14) by @QuantumExplorer in #4948
- fix(dpp)!: refuse immutableAllowSetting on a deletableDocument reference (PV14) by @QuantumExplorer in #4983
- fix(dpp): parse nested required and transient entries by prefix by @QuantumExplorer in #5050
- fix(dpp): restore the shipped order of basic consensus errors by @QuantumExplorer in #5053
- fix(dpp)!: refuse token cost and unruled keyword changes on update with a consensus error (PV14) by @QuantumExplorer in #5069
- fix(dpp): read $entropy as base64, not base58, in the create-transition map parser by @shumkov in #5072
- fix(dpp)!: propertyConstraints compare identifier properties that declare refersTo (PV14) by @QuantumExplorer in #5073
- fix(dpp)!: accept a reordered entryPayload and refuse unruled keywords as incompatible (PV14) by @QuantumExplorer in #5074
- fix(dpp)!: report contracts refused by parser generation 3 as consensus errors (PV14) by @QuantumExplorer in #5076
- fix(dpp)!: size estimates of strings of 16384 or more characters no longer overflow (PV14) by @QuantumExplorer in #5086
- fix(dpp)!: propertyConstraints read empty objects as absent and follow $defs refs (PV14) by @QuantumExplorer in #5101
- fix(dpp)!: refuse a dotted property path in sum and average keywords (PV14) by @QuantumExplorer in #5104
- fix(dpp): pass the contract's $defs to the countOf and sumOf key enum check by @QuantumExplorer in #5110
- fix(dpp)!: bound schema
$refwalks that hang proposers and check_tx (PV14) by @PastaPastaPasta in #5317 - fix(dpp)!: reject repeated nested document keys in PV14 by @shumkov in #5326
- fix(dpp): preserve wasm class mismatch diagnostics by @shumkov in #5428
- fix(dpp)!: refuse hash key data that is not 20 bytes at protocol version 14 by @shumkov in #5463
- fix(dpp): compile without default features by @QuantumExplorer in #5498
Drive & Drive-ABCI
- fix(platform): reject contradictory keep-history document deletes by @QuantumExplorer in #4218
- fix(drive)!: make shared-prefix aggregate indexes insertable at protocol v14 by @QuantumExplorer in #4265
- fix(drive): derive wasm-drive-verify platform version cap from rs-platform-version by @QuantumExplorer in #4269
- fix(drive-abci)!: cross-check the contested index of a prefunded voting balance at protocol v14 by @QuantumExplorer in #4281
- fix(drive): skip the ranked offset by counting instead of walking by @shumkov in #4382
- fix(drive)!: cursor pagination over multi-branch query levels dropped sibling-branch documents by @QuantumExplorer in #4396
- fix(drive)!: unique index entries with null fields lost on document update by @QuantumExplorer in #4398
- fix(drive-abci): execute a different block at the same height/round instead of serving the stale context by @QuantumExplorer in #4462
- fix(platform): preserve tracked masternode ABI and persistence by @QuantumExplorer in #4473
- fix(drive-abci): mimic block time truncated to whole seconds by @QuantumExplorer in #4477
- fix(drive): reject index-gapped document queries at protocol version 14 by @QuantumExplorer in #4526
- fix(drive-abci): sync mainnet blocks 32326-32329 without crash-restarts by @PastaPastaPasta in #4536
- fix(drive): keep cursor document in descending continuation-page proofs by @QuantumExplorer in #4541
- fix(platform)!: decode remote input with untrusted bincode and disk loads with trusted decoders by @QuantumExplorer in #4625
- fix(drive-abci)!: reject contested document id collisions by @PastaPastaPasta in #4662
- fix(drive-abci): bound and deduplicate SpecificKeys identity key requests by @QuantumExplorer in #4724
- fix(drive): scope compound cursor bounds to matching branches by @QuantumExplorer in #4726
- fix(drive): verify composite page and lookup components under their lifted limits by @QuantumExplorer in #4729
- fix(drive-abci)!: fail expired withdrawals below Core's dust threshold instead of re-signing them forever by @QuantumExplorer in #4737
- fix(drive-abci): keep a committed block final when its post-commit checkpoint fails by @QuantumExplorer in #4748
- fix(drive): bump grovedb so a ranking over an unwritten pinned prefix proves an empty page by @QuantumExplorer in #4753
- fix(platform): load persisted protocol version votes before the epoch tally by @QuantumExplorer in #4754
- fix(drive): make the data contract cache transaction-aware by @QuantumExplorer in #4755
- fix(drive)!: recreate the abstain and lock vote trees over orphaned storage when a resource is contested again by @QuantumExplorer in #4758
- fix(platform)!: apply the review of contract group key bounds by @QuantumExplorer in #4801
- fix(drive-abci): re-validate identityPublicKey references when only the key id changes by @QuantumExplorer in #4812
- fix(drive-abci): refuse indexOnly creates that collide within one batch by @QuantumExplorer in #4813
- fix(drive)!: create distribution trees for tokens added by contract update by @QuantumExplorer in #4834
- fix(drive)!: mint base supply of tokens added by contract update by @QuantumExplorer in #4835
- fix(drive)!: bound pre-programmed distribution amounts and queue a shared release-time tree once by @QuantumExplorer in #4837
- fix(drive): store the current-key alias for bound encryption/decryption keys under the purpose subtree by @PastaPastaPasta in #4843
- fix(drive-abci): recheck re-validates the document action fee agreement by @QuantumExplorer in #4900
- fix(drive-abci): refuse a masternode vote on an unfunded poll as an unpaid consensus error by @QuantumExplorer in #4904
- fix(platform)!: drop transient values on replace and refuse declarations that read them (PV14) by @QuantumExplorer in #4950
- fix(drive-abci)!: bill the contract fetch of a fee claim deterministically by @QuantumExplorer in #4954
- fix(platform)!: register the version 14 system contracts without storage flags by @QuantumExplorer in #4956
- fix(drive): credit other identities' refunds when the payer's refund equals its fee by @QuantumExplorer in #4960
- fix(drive-abci): a failed identity create from addresses keeps its input balances and books its penalty by @QuantumExplorer in #4961
- fix(drive-abci): a failed identity create from addresses pays a flat penalty by @QuantumExplorer in #4966
- fix(drive-abci)!: refuse an identity create from addresses with a failed key signature unpaid (PV14) by @QuantumExplorer in #4968
- fix(drive-abci)!: re-check a contract reference's owner requirement on every replace of a transferable document (PV14) by @QuantumExplorer in #4982
- fix(drive-abci)!: refuse a $creatorId key reference on a document without a creator id (PV14) by @QuantumExplorer in #4984
- fix(platform)!: credit repaid identity debt to the processing fee pool by @QuantumExplorer in #4985
- fix(drive)!: merge repeated writes of one balance in a batch so an action fee no longer loses a purchase price by @QuantumExplorer in #4987
- fix(drive-abci): a transition whose version is not active is not a decode failure by @shumkov in #4993
- fix(drive)!: delete an ended vote poll end date only once none of its polls remain (PV14) by @QuantumExplorer in #4996
- fix(drive-abci)!: refuse a token mint or direct purchase past the i64::MAX supply ceiling (PV14) by @QuantumExplorer in #5000
- fix(drive-abci)!: refuse a masternode vote for an identity that is not a contender (PV14) by @QuantumExplorer in #5002
- fix(drive-abci): check the address input limit before verifying witnesses by @QuantumExplorer in #5005
- fix(drive): read stored group actions without the proof decoding budget by @QuantumExplorer in #5006
- fix(drive-abci): verify vote extensions against the withdrawals of their own round by @QuantumExplorer in #5010
- fix(drive-abci)!: refuse bytes after a state transition (PV14) by @QuantumExplorer in #5011
- fix(drive-abci)!: claw a storage refund back from the epochs it was priced for (PV14) by @QuantumExplorer in #5013
- fix(drive-abci)!: record and check the nullifiers of shielding transitions (PV14) by @QuantumExplorer in #5014
- fix(drive)!: an evonode's token claim covers only the epochs it read (PV14) by @QuantumExplorer in #5015
- fix(drive-abci): sign and verify vote extensions of a block accepted in another round by @QuantumExplorer in #5028
- fix(drive-abci)!: cap a contest at 1,000 contenders and tally every one (PV14) by @QuantumExplorer in #5029
- fix(platform)!: contenders state the most they pay and are charged the join price (PV14) by @QuantumExplorer in #5039
- fix(drive-abci): sign a locked block when a later proposal left no execution context by @QuantumExplorer in #5079
- fix(drive-abci): finalize a block accepted in an earlier round after a later proposal was refused by @QuantumExplorer in #5081
- fix(drive-abci): sign vote extensions only for blocks this node accepted by @QuantumExplorer in #5084
- fix(drive): refuse indexOnly prefix pivots whose pages could be incomplete by @QuantumExplorer in #5103
- fix(drive)!: subscription filters match generated properties a transition leaves out by @QuantumExplorer in #5114
- fix(platform)!: refuse own-type totals on contested types and fail loudly on unread totals (PV14) by @QuantumExplorer in #5115
- fix(platform)!: a preallocated agreement source must fit a tree key (PV14) by @QuantumExplorer in #5123
- fix(drive)!: refuse a duplicate value in a unique index on a nested property (PV14) by @QuantumExplorer in #5127
- fix(drive-abci): check_tx refuses a masternode vote a block would refuse by @QuantumExplorer in #5137
- fix(drive)!: index null flags follow each index's own path (PV14) by @QuantumExplorer in #5173
- fix(platform)!: review fixes for derived index properties reading kept fields (PV14) by @QuantumExplorer in #5224
- fix(platform)!: review fixes for outlivesDelete (PV14) by @QuantumExplorer in #5233
- fix(platform)!: refuse a by-id refersTo to an indexOnly document type at registration (PV14) by @QuantumExplorer in #5284
- fix(platform)!: a BLS12_381 identity key's signature must verify (PV14) by @QuantumExplorer in #5295
- fix: verify actions in mixed active and closed groups by @shumkov in #5314
- fix(drive-abci): sign the asset unlock serialization hash instead of the txid by @shumkov in #5315
- fix(platform)!: empty end dates no longer stall contested vote poll resolution (PV14) by @QuantumExplorer in #5321
- fix: omit unrelated co-signer balances from group burn proofs by @shumkov in #5324
- fix(platform)!: enforce token policy on document payments by @shumkov in #5325
- fix(drive): verify chained pages that fan out across an index prefix by @QuantumExplorer in #5328
- fix(drive-abci)!: validate property constraints on moderator restores by @shumkov in #5329
- fix(platform): answer query request errors with INVALID_ARGUMENT by @QuantumExplorer in #5333
- fix(platform): backfill historical credit nullifiers at pv14 activation by @shumkov in #5341
- fix: classify unsupported offsets and composite limits by @shumkov in #5349
- fix(platform)!: key unsigned integer index values in value order by @QuantumExplorer in #5350
- fix(platform): verify signed protocol versions and use one identity proof by @shumkov in #5361
- fix(drive): let startAt and startAfter page documentsSummable types (PV14) by @QuantumExplorer in #5376
- fix(drive)!: fee estimates size sum and count index trees as what they are (PV14) by @QuantumExplorer in #5377
- fix(platform)!: decode Core v24 blocks and transactions by @shumkov in #5392
- fix(platform)!: charge a sponsored batch's fee increase to its signer (PV14) by @QuantumExplorer in #5398
- fix(drive-abci)!: return missing proposer payouts to processing pool by @shumkov in #5399
- fix(platform)!: keep unknown Core payload layouts decodable by @shumkov in #5403
- fix(drive-abci): guard accepted token pool nullifiers within batches by @shumkov in #5411
- fix(platform): start on Dash Core v24, which no longer reports softforks in getblockchaininfo by @shumkov in #5422
- fix(drive-abci)!: refuse IdentityCreate identity id and key proof failures before they consume the asset lock by @shumkov in #5431
- fix(drive): add masternode identity keys through a dedicated operation by @shumkov in #5456
- fix(drive-abci)!: keep the operator identity when Core re-encodes the same operator key by @shumkov in #5461
- fix(drive-abci): send ChainLocks to Core with the block hash in display order by @shumkov in #5490
Platform Wallet
- fix(platform-wallet): emit the real locking script for spent UTXOs by @Claudius-Maginificent in #4257
- fix(platform-wallet): age-guard the finalized-transaction handle broadcast by @bfoss765 in #4309
- fix(platform-wallet): batch wallet-event persistence + expose sync_fault (watermark-freeze mitigations) by @bfoss765 in #4314
- fix(platform-wallet): lossless mpsc persistence drain — root-cause fix for the sync-watermark freeze by @bfoss765 in #4315
- fix(platform-wallet): type signer-reported missing key as MessageSigningKeyUnavailable by @QuantumExplorer in #4321
- fix(platform-wallet): make asset-lock spends visible to every balance reader by @HashEngineering in #4336
- fix(platform-wallet): reject trailing bytes in persisted asset-lock proof blobs by @QuantumExplorer in #4346
- fix(platform-wallet): finalize reconstructed asset locks as RecoveredFromChain, in-session by @QuantumExplorer in #4347
- fix(platform-wallet): report an unanswered identity scan as incomplete, not empty by @romchornyi in #4352
- fix(platform-wallet): wait for SPV transport before resuming asset locks that need broadcast by @QuantumExplorer in #4355
- fix(platform-wallet): fail a double-spending asset lock with a typed terminal error by @QuantumExplorer in #4356
- fix(platform-wallet): preserve reported-consumed asset-lock recovery by @llbartekll in #4357
- fix(platform-wallet): raise the invitation cap to cover the contested username tier by @bfoss765 in #4362
- fix(platform-wallet): stop a contact's watch-only chain from defining the persisted transaction row by @bfoss765 in #4363
- fix(platform-wallet): stale-islock to chainlock fallback for the L1 invite claim by @bfoss765 in #4364
- fix(platform-wallet): survive an ambiguous re-broadcast when resuming a Built asset lock by @QuantumExplorer in #4367
- fix(platform-wallet): gate candidate-address re-export behind shielded feature by @QuantumExplorer in #4369
- fix(platform-wallet): commit wallet events off the async runtime by @romchornyi in #4370
- fix(platform-wallet): accept legacy dashj key purposes on inbound contact requests by @romchornyi in #4372
- fix(platform-wallet): fold fetched on-chain state into already-known identities on load by @QuantumExplorer in #4374
- fix(platform-wallet): harden asset-lock recovery — invisible chain-locked rows, two unbounded waits by @bfoss765 in #4422
- fix(platform-wallet): stop the startup sequence reporting integrity it did not establish by @bfoss765 in #4426
- fix(platform-wallet): fold per-account records into one wallet-level row, owned roles winning collisions by @HashEngineering in #4438
- fix(platform-wallet): estimate shielded fees at the network's active protocol version by @QuantumExplorer in #4470
- fix(platform-wallet): use dash-spv's own acceptance timeout instead of a 30s override by @Claudius-Maginificent in #4481
- fix(platform-wallet): re-seed shield regression fixture for the protocol 14 fee rebalance by @QuantumExplorer in #4489
- fix(platform-wallet): never drop a wallet event on the wallets-map lock by @romchornyi in #4557
- fix(platform-wallet-storage): durably apply swept transactions in the SQLite store by @romchornyi in #4559
- fix(platform-wallet): act on swept transactions at the persistence seam by @romchornyi in #4560
- fix(platform-wallet): bound bincode decode size on asset-lock proof bytes by @Claudius-Maginificent in #4585
- fix(platform-wallet): typed persister errors with caller-visible retry classification by @Claudius-Maginificent in #4586
- fix(platform-wallet): dead registration scan, recursive asset-lock read, poller off main by @llbartekll in #4611
- fix(platform-wallet): close the asset-lock resume broadcast race by @shumkov in #4636
- fix(platform-wallet): serialize pending crypto writes with identity removal by @lklimek in #4649
- fix(platform-wallet): resolve a swept sent payment's verdict on the round that swept it by @romchornyi in #4651
- fix(platform-wallet): support HASH160 DashPay profile signing keys by @lklimek in #4653
- fix(platform-wallet): give an unconfirmed outgoing send an owner across a restart by @romchornyi in #4659
- fix(platform-wallet): look up the funding tx's block when a ChainLock proof has no record height by @romchornyi in #4738
- fix(platform-wallet)!: persist DashPay coreHeight backfill coverage so a relaunch resumes instead of rewinding again by @HashEngineering in #5026
- fix(platform-wallet): a ProUpServTx always carries an output by @QuantumExplorer in #5105
- fix(platform-wallet): report an identity balance refusal on withdrawal as insufficient credits by @romchornyi in #5206
- fix(platform-wallet-storage): open the wallet store on Android by @HashEngineering in #5352
- fix(platform-wallet): store the InstantSend lock of a send on its record by @romchornyi in #5393
- fix(platform-wallet): build version-3 ProUpServTx for Core v24 masternodes by @shumkov in #5408
- fix(platform-wallet): find a masternode's operator identity after Core re-encodes its operator key by @shumkov in #5462
- fix(platform-wallet): build version-3 evonode ProUpServTx once the SPV coinbase shows V24 by @shumkov in #5497
Swift SDK / iOS Example App
- fix(swift-example-app): gate identity resumes by funding type by @thepastaclaw in #4015
- fix(swift-sdk): gate the ordered bring-up on the seed actually owning the wallet by @romchornyi in #4368
- fix(swift-sdk): build the shippable profile by default by @romchornyi in #4371
- fix(swift-sdk): isLocal = mine-or-tracked; promote wallet identities, fix observed-entry mislinking by @QuantumExplorer in #4375
- fix(swift-sdk): drain the persister's autorelease pool per row by @romchornyi in #4414
- fix(swift-sdk)!: bound contested username loading by @PastaPastaPasta in #4485
- fix(swift-sdk): act on swept transactions in the SwiftData store by @romchornyi in #4589
- fix(swift-sdk): stop born-spent TXO rows at the persistence seam and reconcile the store after a full scan by @llbartekll in #4638
- fix(swift-sdk)!: expose reservation-aware local shielded balance snapshots by @llbartekll in #4709
- fix(swift-sdk)!: restore historical V2 migration to live V3 by @llbartekll in #4910
- fix(swift-sdk): stop SPV off the main thread by @llbartekll in #4994
- fix(swift-sdk): take migration copies out of WAL mode by @romchornyi in #5070
- fix(swift-sdk): free FFI errors in state-transition wrappers by @QuantumExplorer in #5117
- fix(swift-sdk): documentTransfer handles a missing document and signs once by @QuantumExplorer in #5120
- fix(swift-sdk): stop shielded sync off the main thread by @llbartekll in #5202
Kotlin SDK / Android Example App
- fix(kotlin-sdk): unmanaged-identity reads return absence + typed SigningKeyUnavailable (split from #4183) by @bfoss765 in #4191
- fix: restore four Swift-parity guards in the Kotlin SDK, plus two DPNS marketplace defects by @bfoss765 in #4423
- fix(kotlin-sdk): typed retryable device-locked keystore errors + createWallet fail-fast by @bfoss765 in #4463
- fix(kotlin-sdk): skip JReleaser's POM lint, which rejects Android's aar packaging by @HashEngineering in #4759
- fix(kotlin-sdk): prepare secure emulator state in nightly tests by @ktechmidas in #5131
DAPI & Networking
- fix(dapi): truthful state sync status, health height field collision, client crash on absent sections by @PastaPastaPasta in #4532
- fix(dapi): classify malformed protobuf requests as invalid arguments by @shumkov in #5351
- fix(rs-dapi): keep the Core RPC permit until the call returns by @QuantumExplorer in #5507
Dashmate
- fix(dashmate): use live Tenderdash app version for protocol status by @thepastaclaw in #4136
- fix(dashmate): stop concurrent commands reverting each other's config changes by @shumkov in #4248
- fix(dashmate): extend Core shutdown grace period by @thepastaclaw in #4307
- fix(dashmate): detect and report gateway certificate problems by @shumkov in #4420
- fix(dashmate): deliver renewed certificates to the running gateway by @shumkov in #4421
- fix(dashmate): add dedicated onion bind for Core 24 by @shumkov in #5342
- fix(dashmate): reload the local quorum list every second by @QuantumExplorer in #5354
- fix(dashmate): move stock 4.x and 5-rc Platform image tags to the release defaults on update by @shumkov in #5433
- fix(dashmate): show platform status on Dash Core v24 by @shumkov in #5458
Other Fixes
- fix(test-suite): stabilize platform e2e tests by @shumkov in #4214
- fix(release): base changelog on the immediately-preceding release by @shumkov in #4229
- fix: parallel-test race on process-global platform version in contract to_value by @QuantumExplorer in #4395
- fix(contract): use the keyword-search contract id in the feature-less fallback by @QuantumExplorer in #4873
- fix(release): build clients natively on unprivileged runners by @PastaPastaPasta in #5068
- fix(release)!: run NPM and Kotlin releases on disposable runners by @infraclaw-dash in #5077
- fix: repair headless Swift, RocksDB and doctest CI by @ktechmidas in #5129
- fix: update trusted runner image controller pin by @ktechmidas in #5134
- fix: validate runner candidates using full commit statuses by @infraclaw-dash in #5156
- fix(ci): resolve Swift simulator test destinations by UDID by @infraclaw-dash in #5257
Refactoring
- refactor(dpp): extract shared try_from_schema parsing helpers by @QuantumExplorer in #4276
- refactor(sdk): remove deprecated v1 split build/sign transaction surface by @QuantumExplorer in #4323
- refactor(sdk): drop the vestigial v2 suffix from the finalized-transaction surface by @QuantumExplorer in #4325
- refactor(rs-sdk-ffi): use the rs-sdk voting-key helpers instead of its own by @QuantumExplorer in #4341
- refactor(sdk)!: extract transport-free query core into dash-platform-queries by @PastaPastaPasta in #4388
- refactor(dpp): split document serialization formats into per-generation files by @QuantumExplorer in #4484
- refactor(platform-wallet-storage)!: delete removed identities instead of tombstoning by @Claudius-Maginificent in #4496
- refactor(platform-wallet): share provider-key account reconstruction by @Claudius-Maginificent in #4587
- refactor(dpp): share one is_transient helper for lookup sources and encryptedFor by @QuantumExplorer in #4949
- refactor(dpp): remove the empty moderation charter validation step by @QuantumExplorer in #4970
- refactor(dpp): restore shipped registration_cost v1 index parsing by @QuantumExplorer in #5055
- refactor(drive): create once-per-identity claim trees in insert_contract v2 by @QuantumExplorer in #5056
- refactor(platform): fold DRIVE_ABCI_QUERY_VERSIONS_V3 into V2 by @QuantumExplorer in #5057
- refactor(platform): import instead of inline crate paths in 4.1 and 4.2 code by @QuantumExplorer in #5065
- refactor(platform): share the delete state checks and cover what delete rules leave alone by @QuantumExplorer in #5330
- refactor(dpp)!: keep the property type shorthand expansion out of shipped generations by @QuantumExplorer in #5357
- refactor(dpp): decode instant asset lock proofs with rust-dashcore's legacy asset lock decoder by @shumkov in #5423
Tests
- test(swift-sdk): cover imported-wallet history either side of registration by @ZocoLini in #4064
- test(drive-abci): gate PR runs to one comprehensive chain simulation by @QuantumExplorer in #4297
- test(sdk): add proof-vector regression corpus for drive-proof-verifier by @PastaPastaPasta in #4345
- test(drive): pin the batch-transition cap and land the phantom-group evidence by @shumkov in #4383
- test(swift-sdk): make resolver sign tests hermetic to CI keychain state by @QuantumExplorer in #4386
- test(drive-abci): pin the mainnet shield-halt fix with regression and fault-injection tests by @QuantumExplorer in #4408
- test(swift-sdk): pin non-English BIP-39 mnemonic support against the fixed FFI by @PastaPastaPasta in #4454
- test(dashmate): make ZeroSSL provider-change test deterministic by @QuantumExplorer in #4482
- test(test-suite): indexOnly document lifecycle functional spec by @PastaPastaPasta in #4510
- test(dashmate): use a sentinel wake-up counter the clock cannot collide with by @shumkov in #4565
- test(drive-abci): chained trust-boundary suite — SDK entry points against server proofs by @QuantumExplorer in #4568
- test(platform-wallet): cover insert_platform_node_pool_entry and its error paths by @Claudius-Maginificent in #4628
- test(dpp): stabilize distribution evaluator tests by @PastaPastaPasta in #4656
- test(platform-wallet-storage): make restore exclusion probes conclusive by @QuantumExplorer in #4714
- test(dpp): run deep value serialization tests on a large stack by @QuantumExplorer in #4725
- test: withdraw above the protocol 14 minimum in the JS withdrawal tests by @QuantumExplorer in #4781
- test(drive-abci): pin that a token config update cannot set a perpetual distribution by @QuantumExplorer in #4836
- test(drive-abci): check every strategy test's state against the GroveDB structure by @QuantumExplorer in #4847
- test(drive): pin that chained and composite joins prove the absence of a referenced document by @QuantumExplorer in #4852
- test(dpp): guard doctype keyword names against stray keys of contracts admitted under meta-schema v0 by @QuantumExplorer in #4855
- test(drive-abci): replay the version 10 upgrade events on a chain born at 10 by @QuantumExplorer in #4958
- test(drive): keep setup_drive's temp directory alive while the drive is open by @QuantumExplorer in #5003
- test(swift-sdk): run SDKMethodTests against the offline mock SDK instead of live testnet by @QuantumExplorer in #5009
- test(drive): pin that a cached contract read after an in-block update bills like a cold read by @QuantumExplorer in #5052
- test: follow the test conventions in tests added in 4.1 and 4.2 by @QuantumExplorer in #5062
- test(sdk): ifThen and ifThenElse rules through rs-sdk-ffi and the Swift and Kotlin SDKs by @QuantumExplorer in #5106
- test(rs-sdk): poll for missing-owner exclusions to expire instead of racing a fixed sleep by @QuantumExplorer in #5218
- test(dashmate): assert the migrated config format version, not a literal by @shumkov in #5241
- test(swift-sdk): fix the two failing Swift SDK unit tests on v5.0-dev by @QuantumExplorer in #5297
- test(sdk): re-record GroveDB V0 offline vectors as V1 and re-enable their tests by @QuantumExplorer in #5299
- test(drive-abci): verify query errors over gRPC and original proofs by @shumkov in #5343
- test(drive-abci): require the estimate, not the actual fee, for a 128-output transfer to addresses by @QuantumExplorer in #5385
- test(platform-wallet-storage): build the integration tests as one binary by @PastaPastaPasta in #5397
- test(platform-wallet-storage): move the Core transaction rows test into the integration binary by @QuantumExplorer in #5415
- test(drive-abci): expect the not-active consensus error in every pre-activation test by @shumkov in #5502
- test(drive-abci): expect the not-active consensus error in the remaining pre-activation tests by @shumkov in #5508
Performance
- perf(platform-wallet): keep the contact fetch off the drain's repeating-rejection path by @romchornyi in #4373
- perf(sdk): reuse connections via sticky address rotation by @PastaPastaPasta in #4545
- perf(drive-abci): remove historical withdrawal status diagnostic by @PastaPastaPasta in #4569
- perf(drive-abci): don't create GroveDB checkpoints while replaying history by @PastaPastaPasta in #4570
- perf(drive-abci): stop rewriting the whole platform state every block by @PastaPastaPasta in #4571
- perf(drive-abci): fetch the next core height's masternode and quorum lists ahead of time by @PastaPastaPasta in #4572
- perf(wasm-sdk): fetch quorums concurrently and skip masternode discovery when addresses are given by @QuantumExplorer in #4766
- perf(drive): build batch deletes without copying the pending batch by @QuantumExplorer in #5004
- perf(drive-abci): read shielded encrypted notes in one chunk-aligned range read by @QuantumExplorer in #5030
- perf(wasm-sdk): speed up release WASM optimization by @ktechmidas in #5147
Documentation
- docs(agents): never commit working specs; enforce by discipline, not git plumbing by @shumkov in #4245
- docs(platform-wallet): error-code registry for the FFI result space by @bfoss765 in #4318
- docs(wasm-sdk): clarify aggregate groupBy behavior by @thephez in #4576
- docs(platform-wallet): make comments explain the decision, not the PR history by @llbartekll in #4594
- docs(drive): update ranked dispatcher docs stale since pinned-prefix form by @QuantumExplorer in #4606
- docs(platform): add coding conventions chapter and refresh versioning chapters by @QuantumExplorer in #4650
- docs(platform): say why in-place edits to shipped generations are inert by @QuantumExplorer in #5054
- docs: remove committed working specs and plans by @QuantumExplorer in #5060
- docs(platform): document the genesis protocol version exception and Swift/Kotlin indentation by @QuantumExplorer in #5061
- docs(platform): add Parameters and Returns sections to 4.1 and 4.2 dispatchers by @QuantumExplorer in #5063
- docs: add a contract keywords reference page to the book by @QuantumExplorer in #5067
- docs: give every contract keyword its own chapter in the book by @QuantumExplorer in #5075
- docs: list the complete contract language in the keywords overview by @QuantumExplorer in #5082
- docs: encrypt the 69-byte compact xpub in the contact-request guide by @QuantumExplorer in #5087
- docs(platform): give token pools a unique PV14 change number by @shumkov in #5300
- docs: correct nonce validation wording by @shumkov in #5362
- docs: write identifiers and fixed-size byte arrays with the type shorthands in the book by @QuantumExplorer in #5378
Build & Dependencies
- chore(platform-wallet): bump key-wallet pin and migrate to new AddressState/asset-lock API by @QuantumExplorer in #4305
- chore: update rust-dashcore to b056d07c by @QuantumExplorer in #4343
- chore: bump rust-dashcore to the latest dev revision by @QuantumExplorer in #4381
- chore: bump rust-dashcore to the latest dev revision by @QuantumExplorer in #4394
- chore: bump rust-dashcore pin for multilingual BIP-39 mnemonic parsing by @llbartekll in #4455
- chore: bump rust-dashcore to the merged sync fixes, minus the sweep-event chain by @romchornyi in #4459
- build: bump grovedb to develop 0a3b3f9b (re-key churn as replaced bytes) by @QuantumExplorer in #4528
- chore: bump grovedb to 33a3ad34 (per-instance query limits) by @QuantumExplorer in #4564
- chore: bump grovedb to 97250247 (per-instance limit review follow-ups) by @QuantumExplorer in #4566
- chore: bump grovedb to 2d95c567 (#850 merged: limited branches graft below a shared key) by @QuantumExplorer in #4597
- chore: bump grovedb to 6fc7e1e8 (#851 merged: synthesized split bodies keep the inputs' direction) by @QuantumExplorer in #4602
- build: make the workspace lockfile vendorable with --locked by @PastaPastaPasta in #4631
- build(platform)!: adopt GroveDB 6.0 with automatic backward references and grovedb-bincode 2.1.0 by @QuantumExplorer in #4635
- build: upgrade rs-tenderdash-abci and Tenderdash image to v1.8.0 by @Claudius-Maginificent in #4661
- build: update rust to 1.98.1 by @QuantumExplorer in #4721
- chore(dashmate): use Tenderdash 1.8.x image by @lklimek in #4944
- build: bump grovedb so a limit-cut V1 proof hides its range bound by @QuantumExplorer in #5305
- build!: bump grovedb to 6.1.0 by @QuantumExplorer in #5414
- build: install the downloaded cargo-binstall instead of reinstalling it by @shumkov in #5424
- chore: bump GroveDB to 6.1.1, h2, rustls, quinn-proto, crossbeam-epoch and rust_decimal for RUSTSEC advisories by @QuantumExplorer in #5499
- chore(deps): fix critical and high npm audit advisories by @QuantumExplorer in #5500
- chore(platform)!: update rust-dashcore to v0.45.0 by @shumkov in #5517
- chore: bump rustls-webpki and webpki-roots for RUSTSEC-2026-0381/0382/0383 by @QuantumExplorer in #5582
- chore: bump rs-tenderdash-abci to v1.8.1 for zip RUSTSEC-2026-0367/0368/0369 by @QuantumExplorer in #5583
CI / CD
- ci: tolerate book preview comment permission errors by @thepastaclaw in #3635
- ci: release Kotlin and Swift SDKs with the platform release by @shumkov in #4228
- ci: schedule Rust workspace tests on macOS or Linux self-hosted runners by @QuantumExplorer in #4287
- ci: remove the CodeRabbit/PastaClaw AI review gate by @QuantumExplorer in #4292
- ci: skip shielded Rust tests on PRs without shielded changes by @QuantumExplorer in #4293
- ci: install Rust lint components for workspace tests by @vivekgsharma in #4294
- ci: keep coverage-instrumented build between runs by @QuantumExplorer in #4296
- ci: lint test targets with clippy --all-targets by @QuantumExplorer in #4330
- ci(kotlin-sdk): run tests on dedicated self-hosted runner by @vivekgsharma in #4468
- ci(swift-sdk): authenticate setup-protoc against the anonymous rate limit by @QuantumExplorer in #4517
- ci: build release SDKs and NPM packages on self-hosted runners by @PastaPastaPasta in #4562
- ci: restore Rust dependency security auditing by @PastaPastaPasta in #4621
- ci: verify preinstalled macOS build dependencies by @PastaPastaPasta in #4646
- ci: remove host privilege requirements from persistent Linux runners by @infraclaw-dash in #4702
- ci: re-pin the shared review engine and receive review events directly by @shumkov in #4710
- ci: re-pin the shared review engine and receive review events directly by @shumkov in #4713
- ci: re-pin PR Hygiene and adopt the suite name by @shumkov in #4720
- ci: re-pin PR Hygiene by @shumkov in #4722
- ci(release): wait for published npm packages before packing dashmate by @QuantumExplorer in #4727
- ci: re-pin PR Hygiene by @shumkov in #4736
- ci: move the slowest unit tests to the nightly long-running job by @QuantumExplorer in #4757
- ci: re-pin PR Hygiene by @shumkov in #4761
- ci: re-pin PR Hygiene to cut its GitHub request volume by @shumkov in #4765
- ci: re-pin PR Hygiene so the sweep reaches every pull request by @shumkov in #4770
- ci: re-pin PR Hygiene so its runs queue instead of cancelling by @shumkov in #4773
- ci: re-pin PR Hygiene to read each pull request once by @shumkov in #4778
- ci: wake PR Hygiene only for a comment that can change the answer by @shumkov in #4782
- ci: re-pin PR Hygiene to clone this repository only on its sweep by @shumkov in #4785
- ci: re-pin PR Hygiene to require a green build before asking a human by @shumkov in #4795
- ci: re-pin PR Hygiene so it can verify access granted by the organisation by @shumkov in #4804
- ci: PR Hygiene is the merge gate; CODEOWNERS carries no rules by @shumkov in #4839
- ci: link the GroveDB structure viewer on pull requests that change structure by @QuantumExplorer in #4846
- ci: re-pin PR Hygiene for state labels and /skip-bots by @shumkov in #4861
- ci: run Rust code coverage nightly instead of on every pull request by @QuantumExplorer in #4871
- ci: re-pin PR Hygiene for the checklist in the description by @shumkov in #4888
- ci: re-pin PR Hygiene so a bot line says everything about that bot by @shumkov in #4891
- ci: re-pin PR Hygiene to ask a flaky read once more by @shumkov in #4894
- ci: re-pin PR Hygiene for one name for the author limit by @shumkov in #4902
- ci: bootstrap PR-first runner image publishing by @infraclaw-dash in #4912
- ci: re-pin PR Hygiene by @shumkov in #4935
- ci: re-pin PR Hygiene by @shumkov in #4945
- ci(release): raise NPM and Swift SDK release job timeouts by @shumkov in #4974
- ci: re-pin PR Hygiene by @shumkov in #4975
- ci: re-pin PR Hygiene by @shumkov in #4979
- ci: re-pin PR Hygiene by @shumkov in #4989
- ci: re-pin PR Hygiene by @shumkov in #5016
- ci: re-pin PR Hygiene and wake it on a hand-over by @shumkov in #5020
- ci: re-pin PR Hygiene by @shumkov in #5023
- ci: let the SDK release workflows rebuild tags older than v4.2.0-beta.5 by @QuantumExplorer in #5107
- ci: use pinned ARM64 Rust images on Mac-backed Linux runners by @infraclaw-dash in #5124
- ci(kotlin-sdk): resolve release NDK from runner environment by @ktechmidas in #5141
- ci: deploy isolated PR Hygiene engine on v4.2 by @infraclaw-dash in #5142
- ci: restore legacy runner image template compatibility by @infraclaw-dash in #5155
- ci: pin integrated runner controller revision by @infraclaw-dash in #5157
- ci: keep optional S3 cache outages from failing image builds by @infraclaw-dash in #5165
- ci: recheck the current PR before selecting its candidate by @infraclaw-dash in #5168
- ci: adopt verified exact-contract candidate image reuse by @infraclaw-dash in #5171
- ci: isolate new ordinary AMD64 image contracts from legacy pools by @infraclaw-dash in #5174
- ci: re-pin PR Hygiene engine to 3b98772 by @shumkov in #5193
- ci(release): build dashmate packages from the release's own npm tarballs by @QuantumExplorer in #5235
- ci: run PR Hygiene's engine from master by @shumkov in #5247
- ci(swift-sdk): take the schema freeze base from the default branch by @llbartekll in #5293
- ci(release): notarize dashmate macOS packages with an App Store Connect API key by @romchornyi in #5344
- ci(release): keep cpu-features out of the dashmate macOS package by @romchornyi in #5347
- ci(release): add a manual rehearsal for dashmate macOS notarization by @romchornyi in #5348
- ci(swift-sdk): refresh open schema freeze PRs after Swift SDK changes by @llbartekll in #5413
- ci: run short PR jobs on self-hosted light runners by @PastaPastaPasta in #5468
- ci: fall back to GitHub-hosted runners when DASH_LIGHT_RUNNER is unset by @PastaPastaPasta in #5469
Chores & Maintenance
- chore: fix rustfmt drift on v4.2-dev by @QuantumExplorer in #4278
- Revert "feat(platform-wallet): add encrypted txMetadata document support" by @QuantumExplorer in #4279
- chore(swift-sdk): remove Account.derivePrivateKeyWIF by @QuantumExplorer in #4339
- chore: adopt the shared PR review policy from dashpay/stale_prs_are_bad by @QuantumExplorer in #4449
- chore(skills): rename review-prs to prs by @shumkov in #4787
- chore: mark protocol 14 as shipped and drop the wasm-dpp errorsText test helper by @QuantumExplorer in #4806
- chore: open every pr-description output with a basic explanation section by @QuantumExplorer in #5031
- chore: sync the pr-description skill with the PR template and title check by @QuantumExplorer in #5032
- chore(swift-sdk): freeze App Store schema 3.0.0 by @llbartekll in #5035
- chore(swift-sdk): freeze App Store schema 3.0.0 by @llbartekll in #5209
- chore(skills): show each reviewer their part in /prs by @shumkov in #5242
- chore(swift-sdk): freeze App Store schema 3.0.0 by @llbartekll in #5368
Release Bumps
- chore(release): update changelog and bump version to 4.2.0-dev.1 by @shumkov in #4379
- chore(release): update changelog and bump version to 4.2.0-dev.2 by @QuantumExplorer in #4490
- chore(release): update changelog and bump version to 4.2.0-dev.3 by @QuantumExplorer in #4513
- chore(release): update changelog and bump version to 4.2.0-dev.5 by @QuantumExplorer in #4518
- chore(release): update changelog and bump version to 4.2.0-dev.6 by @QuantumExplorer in #4542
- chore(release): update changelog and bump version to 4.2.0-dev.7 by @QuantumExplorer in #4551
- chore(release): update changelog and bump version to 4.2.0-dev.8 by @PastaPastaPasta in #4591
- chore(release): update changelog and bump version to 4.2.0-dev.9 by @QuantumExplorer in #4723
- chore(release): update changelog and bump version to 4.2.0-dev.10 by @QuantumExplorer in #4732
- chore(release): update changelog and bump version to 4.2.0-dev.11 by @QuantumExplorer in #4756
- chore(release): update changelog and bump version to 4.2.0-beta.1 by @QuantumExplorer in #4803
- chore(release): update changelog and bump version to 4.2.0-beta.2 by @QuantumExplorer in #4821
- chore(release): update changelog and bump version to 4.2.0-beta.3 by @QuantumExplorer in #4867
- chore(release): update changelog and bump version to 4.2.0-beta.4 by @QuantumExplorer in #4972
- chore(release): update changelog and bump version to 4.2.0-beta.5 by @QuantumExplorer in #5044
- chore(release): update changelog and bump version to 4.2.0-beta.6 by @QuantumExplorer in #5128
- chore(release): update changelog and bump version to 4.2.0-beta.7 by @QuantumExplorer in #5199
- chore(release): update changelog and bump version to 5.0.0-beta.1 by @QuantumExplorer in #5234
- chore(release): update changelog and bump version to 5.0.0-beta.2 by @QuantumExplorer in #5304
- chore(release): update changelog and bump version to 5.0.0-beta.3 by @QuantumExplorer in #5340
- chore(release): update changelog and bump version to 5.0.0-beta.4 by @QuantumExplorer in #5363
- chore(release): update changelog and bump version to 5.0.0-beta.5 by @QuantumExplorer in #5386
- chore(release): update changelog and bump version to 5.0.0-beta.6 by @QuantumExplorer in #5401
- chore(release): update changelog and bump version to 5.0.0-rc.1 by @shumkov in #5406
- chore(release): update changelog and bump version to 5.0.0-rc.2 by @shumkov in #5427
- chore(release): update changelog and bump version to 5.0.0-rc.3 by @shumkov in #5436
- chore(release): update changelog and bump version to 5.0.0-rc.4 by @shumkov in #5480
- chore(release): update changelog and bump version to 5.0.0-rc.5 by @shumkov in #5492
- chore(release): update changelog and bump version to 5.0.0-rc.6 by @shumkov in #5509
- chore(release): update changelog and bump version to 5.0.0-rc.7 by @shumkov in #5522
- chore(release): update changelog and bump version to 5.0.0-rc.8 by @shumkov in #5547
New Contributors
- @romchornyi made their first contribution in #4273
- @infraclaw-dash made their first contribution in #4702
Full Changelog: v4.1.2...v5.0.0