Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
231f6ff
feat(drive-abci)!: apply block randomness through the ApplyBlockRando…
QuantumExplorer Nov 3, 2026
0211605
Merge branch 'claude/random-token-amounts' into claude/random-beacon-…
QuantumExplorer Nov 4, 2026
13f4a41
Merge branch 'claude/random-token-amounts' into claude/random-beacon-…
QuantumExplorer Nov 4, 2026
53c2b7d
Merge branch 'claude/random-token-amounts' into claude/random-beacon-…
QuantumExplorer Nov 4, 2026
4ab3d1f
Merge branch 'claude/random-token-amounts' into claude/random-beacon-…
QuantumExplorer Nov 4, 2026
744c163
Merge branch 'claude/random-token-amounts' into claude/random-beacon-…
QuantumExplorer Nov 4, 2026
98306e6
Merge branch 'claude/random-token-amounts' into claude/random-beacon-…
QuantumExplorer Nov 4, 2026
51a2486
Merge branch 'claude/random-token-amounts' into claude/random-beacon-…
QuantumExplorer Nov 4, 2026
a3675aa
Merge branch 'claude/random-token-amounts' into claude/random-beacon-…
QuantumExplorer Nov 4, 2026
1cc7bba
Merge branch 'claude/random-token-amounts' into claude/random-beacon-…
QuantumExplorer Nov 4, 2026
1482040
Merge branch 'claude/random-token-amounts' into claude/random-beacon-…
QuantumExplorer Nov 4, 2026
1a8240b
Merge branch 'claude/random-token-amounts' into claude/random-beacon-…
QuantumExplorer Nov 4, 2026
5d0f0ad
test(drive-abci): settle random token amounts through the block lifec…
QuantumExplorer Nov 4, 2026
2a41a85
Merge branch 'claude/random-token-amounts' into claude/random-beacon-…
QuantumExplorer Nov 4, 2026
e3cf6a6
Merge branch 'claude/random-token-amounts' into claude/random-beacon-…
QuantumExplorer Nov 4, 2026
3df4c35
Merge branch 'claude/random-token-amounts' into claude/random-beacon-…
QuantumExplorer Nov 4, 2026
92a5bc0
Merge branch 'claude/random-token-amounts' into claude/random-beacon-…
QuantumExplorer Nov 4, 2026
dc261cf
docs(changelog): list the Rust API changes of same-block randomness
QuantumExplorer Nov 4, 2026
88378c9
Merge branch 'claude/random-token-amounts' into claude/random-beacon-…
QuantumExplorer Nov 5, 2026
3f1f338
Merge branch 'claude/random-token-amounts' into claude/random-beacon-…
QuantumExplorer Nov 6, 2026
d3450ee
Merge branch 'claude/random-token-amounts' into claude/random-beacon-…
QuantumExplorer Nov 6, 2026
5141f2b
Merge branch 'claude/random-token-amounts' into claude/random-beacon-…
QuantumExplorer Nov 7, 2026
e0fc568
Merge branch 'claude/random-token-amounts' into claude/random-beacon-…
QuantumExplorer Nov 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,22 @@
a required `random_minimum_amount` method, and `TokenTransitionV0Methods` a required
`random_amount_range` method. An implementation outside these crates returns `None` for a
fixed amount.
- **platform-version, dpp, drive-abci (Rust API):** same-block randomness through
`ApplyBlockRandomness` (protocol version 15) changes these items for Rust code whichever
protocol version it runs:
- `DriveAbciBlockEndMethodVersions` gains a public `apply_random_beacon` field. A struct
literal sets it to `None` in a table that does not draw from the beacon.
- `BasicError` gains `RandomBeaconUnavailableError` (code 10604). An exhaustive match needs
the new arm.
- drive-abci's `PlatformState` gains a public `switched_from_protocol_version` field,
`BlockExecutionContextV0` public `random_requests` and `applied_randomness` fields, and
`CleanedCommitInfo` public `beacon` and `app_hash` fields. A struct literal sets them to
`None`, and `random_requests` to `BlockRandomRequests::default()`.
- `PlatformStateV0Methods` gains the required methods `switched_from_protocol_version` and
`set_switched_from_protocol_version`, `BlockExecutionContextV0Getters` the required
methods `random_requests` and `applied_randomness`, and `BlockExecutionContextV0Setters`
the required method `set_applied_randomness`. An implementation outside drive-abci
returns `None`, an empty `BlockRandomRequests`, or ignores the value set.

- **drive, dpp (Rust API):** `Drive::calculate_fee` is now a method and no longer takes
`epochs_per_era` or `previous_fee_versions`:
Expand Down
20 changes: 10 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions book/src/contract-keywords/generated-from.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

`generatedFrom` says that the platform generates a string property's value with a system function of other properties of the same document, its params. The functions change the case of a string (`lowercase`, `uppercase`, `capitalize`, `camelCase`, `snakeCase`), or fold a name so that names differing only by case or by look-alike characters read the same (`homographSafeASCII`): reach for that one when a unique index must treat `Bob`, `BOB` and `B0B` as one name. A client may leave the property out, and the platform generates it when the document arrives; a client that sends it has it checked. The check reads only the document being written, so it costs no state reads.

From protocol version 15 an integer property can be generated too, with `sys.tokens.decimals`: the decimals of the token an identifier property names, read from the token's contract. A value read from state is generated when the document is created and kept after (see [Functions that read state](#functions-that-read-state)). Protocol version 15 also parses `sys.random.uniform`, an integer the platform draws from the block's random beacon, but no protocol version activates it yet: registration refuses it until block execution draws the values (see [Functions drawn at random](#functions-drawn-at-random)).
From protocol version 15 an integer property can be generated too, with `sys.tokens.decimals`: the decimals of the token an identifier property names, read from the token's contract. A value read from state is generated when the document is created and kept after (see [Functions that read state](#functions-that-read-state)). Protocol version 15 also admits `sys.random.uniform`, an integer the platform draws from the block's random beacon once the block's transitions are accepted (see [Functions drawn at random](#functions-drawn-at-random)).

| | |
|---|---|
| **Where** | A string property, at the top level or inside an object; from protocol version 15 also an integer property, for `sys.tokens.decimals` and `sys.random.uniform`. Not on a typed array or its `items`, and not beside `$ref` |
| **Value** | `{ "function": <name>, "params": [<path>, ...] }`: a system function, and as many params as it takes, each the dotted path of a property of the same document type (`"profile.display"` for a nested one), 1 to 256 characters (ASCII, as property names are, so as many bytes). `sys.random.uniform` takes none: `params` may be left out, or be `[]` |
| **Default** | Absent: no rule |
| **Since** | protocol version 14; `sys.tokens.decimals` protocol version 15; `sys.random.uniform` parsed from protocol version 15, refused at registration until a later protocol version activates it |
| **Since** | protocol version 14; `sys.tokens.decimals` protocol version 15; `sys.random.uniform` protocol version 15 |
| **On update** | Fixed: adding, removing or changing it is refused (`IncompatibleDocumentTypeSchemaError`, 10246); a property an update adds may declare it only when one of its params is new too (`DocumentTypeUpdateError`, 40212) |
| **Errors** | `DocumentPropertyNotGeneratedError` (10424) on a document, and from protocol version 15 `ReferencedEntityNotFoundError` (40120) for a token that does not exist; at registration `JsonSchemaError` (10101) or `InvalidContractStructure` (10231); on update `IncompatibleDocumentTypeSchemaError` (10246) or `DocumentTypeUpdateError` (40212) |

Expand Down Expand Up @@ -113,7 +113,7 @@ The `sys.random` functions take no params. The platform draws their value from t
|---|---|---|
| `sys.random.uniform` | An integer drawn uniformly from the property's `minimum` to its `maximum`, both included | An integer property of at most 64 bits declaring both a `minimum` and a `maximum` inside its type, the `minimum` not above the `maximum`, with no `enum`, `const`, `exclusiveMinimum`, `exclusiveMaximum` or `multipleOf`, so every value drawn passes its schema |

Protocol version 15 parses the function, but it is not active at any protocol version yet: registration refuses it with `InvalidContractStructure` (10231), "not active at this protocol version", until block execution draws the values from the beacon Tenderdash delivers. What follows is how it works once a protocol version activates it.
Tenderdash delivers the beacon from its consensus version 2, which protocol version 15 switches it to. Tenderdash applies that switch from the block after the one that moves to protocol version 15, so that first block receives no beacon: a create of a document whose type declares a `sys.random` property is refused there, unpaid, with `RandomBeaconUnavailableError` (10604), and accepted from the next block on. Before protocol version 15, registration refuses the function.

```json
"card": {
Expand Down Expand Up @@ -168,7 +168,7 @@ For a string transformation, the SDK's transition builders generate the property

## Rules at registration

- The keyword is allowed only on a string property (from protocol version 15 also an integer property, for `sys.tokens.decimals`, whose `minimum` and `maximum` admit 0 to 255 and which declares no `enum`, `const`, `exclusiveMinimum`, `exclusiveMaximum` or `multipleOf`, and for `sys.random.uniform` once a protocol version activates it, as described under [Functions drawn at random](#functions-drawn-at-random)), and not beside `$ref`, whose definition replaces every keyword written next to it (declare it in the definition instead). On any other property, a typed array and its `items` included, the meta-schema refuses it (`JsonSchemaError`, 10101).
- The keyword is allowed only on a string property (from protocol version 15 also an integer property, for `sys.tokens.decimals`, whose `minimum` and `maximum` admit 0 to 255 and which declares no `enum`, `const`, `exclusiveMinimum`, `exclusiveMaximum` or `multipleOf`, and for `sys.random.uniform`, as described under [Functions drawn at random](#functions-drawn-at-random)), and not beside `$ref`, whose definition replaces every keyword written next to it (declare it in the definition instead). On any other property, a typed array and its `items` included, the meta-schema refuses it (`JsonSchemaError`, 10101).
- `function` must name a system function, and `params` must list 1 to 16 params, as many as the function takes (none for `sys.random.uniform`, which may leave `params` out). The meta-schema refuses an unknown function or an empty or overlong list (`JsonSchemaError`, 10101).
- Every param must name another string property of the same document type (an identifier property for a `sys.tokens` function; not an object, not a system property, not the declaring property), and that property may not be generated itself.
- A `sys.tokens` function is refused on an [indexOnly](index-only.md) type, whose deletes send their values again where a kept value could not be checked, on a property in a contested index, since a client, which leaves the property out, could not tell whether its document joins a contest, and on a property inside an object declaring `const` or `enum`, which compare the whole object, the value included (to allow some tokens only, declare `enum` on the token property). The property and every object holding it are declared in place, without a `$ref`: a client checks its document with a value the property admits in place of the one it leaves out, and a `$ref` would bring in schemas, the definition's own references and the keywords beside it included, that registration does not judge.
Expand Down
2 changes: 1 addition & 1 deletion book/src/error-handling/error-codes.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Error codes are organized into ranges that correspond to error categories and su
| 10400-10425 | Documents | `DataContractNotPresentError` (10400), `DuplicateDocumentTransitionsWithIdsError` (10401), `DocumentPropertyNotDistinctError` (10419), `InvalidEncryptedPropertyShapeError` (10420), `DocumentPropertyMaxBytesExceededError` (10421), `DocumentPropertyConstraintViolatedError` (10422), `DocumentReferencePreimageInvalidError` (10423), `DocumentPropertyNotGeneratedError` (10424), `DocumentTypePrivateError` (10425) |
| 10450-10460 | Tokens | `InvalidTokenIdError` (10450), `TokenTransferToOurselfError` (10456) |
| 10500-10535 | Identity | `DuplicatedIdentityPublicKeyBasicError` (10500), `InvalidIdentityPublicKeyDataError` (10511) |
| 10600-10603 | State Transition | `InvalidStateTransitionTypeError` (10600), `StateTransitionMaxSizeExceededError` (10602) |
| 10600-10604 | State Transition | `InvalidStateTransitionTypeError` (10600), `StateTransitionMaxSizeExceededError` (10602), `RandomBeaconUnavailableError` (10604) |
| 10700-10700 | General | `OverflowError` (10700) |
| 10800-10818 | Address | `TransitionOverMaxInputsError` (10800), `WithdrawalBelowMinAmountError` (10818) |
| 10819-10827 | Shielded | `ShieldedNoActionsError` (10819), `ShieldedTooManyActionsError` (10825), `ShieldedImplicitFeeCapExceededError` (10826), `ShieldedInvalidDenominationError` (10827 — `IdentityCreateFromShieldedPool` exit amount not a member of the versioned denomination set) |
Expand Down
2 changes: 1 addition & 1 deletion packages/dapi-grpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ serde = ["dep:serde", "dep:serde_bytes", "tenderdash-proto/serde"]
mocks = ["serde", "dep:serde_json"]

[dependencies]
tenderdash-proto = { git = "https://github.com/dashpay/rs-tenderdash-abci", tag = "v1.8.1", default-features = false }
tenderdash-proto = { git = "https://github.com/dashpay/rs-tenderdash-abci", rev = "e80c8a7361eda12918d938acd4ca077478419902", default-features = false }

prost = { version = "0.14" }
futures-core = "0.3.30"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3121,7 +3121,7 @@ fn apply_generated_from_v0(
/// A property may also be generated with `sys.random.uniform`, which takes no parameters
/// (`params` may be left out) and draws an integer from the property's `minimum` to its
/// `maximum`, read into [`GeneratedFrom::range`] ([`uniform_range`]), where the platform
/// version's `random_generated_from` admits it; `None`, in every table for now, refuses it.
/// version's `random_generated_from` admits it (0 at protocol version 15); `None` refuses it.
fn apply_generated_from_v1(
inner_properties: &BTreeMap<String, &Value>,
property_type: &DocumentPropertyType,
Expand Down Expand Up @@ -3229,13 +3229,13 @@ fn apply_generated_from_v1(
.schema
.random_generated_from
{
// Nothing draws the values yet: block execution does not call
// `draw_random_document_properties` until Tenderdash delivers the block's
// random beacon, so a document would keep its placeholder for good
// A table that draws no random values: a document would keep its placeholder
// for good. Unreached by the shipped tables: generation 1 is protocol version
// 15's, whose table admits the function
None => {
return Err(DataContractError::InvalidContractStructure(format!(
"generatedFrom function {function} is not active at this protocol \
version: the platform does not draw random values yet"
version: the platform draws no random values"
)));
}
Some(0) => {
Expand Down
Loading
Loading