Update bsip-0040.md
This commit is contained in:
parent
cf72eaa2d7
commit
f0d16bb517
1 changed files with 26 additions and 25 deletions
51
bsip-0040.md
51
bsip-0040.md
|
@ -39,7 +39,7 @@ The above list of named keys is nothing that is known to the backend as the back
|
|||
|
||||
# Rational
|
||||
|
||||
Custom active permission is a list of `custom active authorities`. A `custom active authority` contains an `operation_id`, an `authority` (just like with active permission) and `asserts` than can be used to restrict arguments and is only valid a certain time period (`valid_from` and `valid_to`). When handling incoming signed transactions, the backend checks for each operation if there is a `custom active authority` for any of its required accounts. Check for every required account of the transaction if all its belonging operations have at least one positively matched `custom active authority` (match means its `authority` is granted through present signatures, same `operationid`, now is within `valid_to` and `valid_from` and all `asserts` pass), and if so grant the active authority of the corresponding account.
|
||||
Custom active permission is a list of `custom active authorities`. A `custom active authority` contains an `operation_id`, an `authority` (just like with active permission) and `restrictions` than can be used to restrict arguments and is only valid a certain time period (`valid_from` and `valid_to`). When handling incoming signed transactions, the backend checks for each operation if there is a `custom active authority` for any of its required accounts. Check for every required account of the transaction if all its belonging operations have at least one positively matched `custom active authority` (match means its `authority` is granted through present signatures, same `operation_id`, now is within `valid_to` and `valid_from` and none of the `restrictions` is violated), and if so grant the active authority of the corresponding account.
|
||||
|
||||
# Specification
|
||||
|
||||
|
@ -47,43 +47,43 @@ All descriptions in this section are on a pseudo/prosa level and no recommendati
|
|||
|
||||
### Custom active permission and custom active authority
|
||||
|
||||
A `custom_active_permission` looks like follows (in JSON-like/pseudo for clarification):
|
||||
A `custom active permission` contains a list of `custom active authorities` and looks like follows (in JSON-like/pseudo for clarification):
|
||||
```
|
||||
custom_active_permission = {
|
||||
account_id, // account that is assigned to this permission
|
||||
authorities = list of custom_active_authority items
|
||||
authorities = list of custom_active_authority objects
|
||||
}
|
||||
custom_active_authority = {
|
||||
valid_from, // timestamp when this is active, defaults to now
|
||||
valid_to, // timestamp when this is invalid, defaults to 1 year
|
||||
operationid, // operationid of the target operation,
|
||||
operation_id, // operation id of the target operation,
|
||||
authority, // same as for the existing authortities (multisig with weighted accounts or keys),
|
||||
asserts // see below
|
||||
restrictions // see below
|
||||
}
|
||||
```
|
||||
Note: This assumes `custom_active_permission` is stored in a separate index. Actual implementation details left to the implementer, as long as every `custom_active_permission` can be assigned to exactly one account.
|
||||
|
||||
A `custom active permission` contains a list of `custom active authority`. `Custom active authority` can match an operation of an incoming, signed transaction. The wording *matching* refers to:
|
||||
- `operationid` is equal to the id of the incoming operation
|
||||
- assigned account of parent `custom active permission` is in the required accounts of the operation
|
||||
A `custom active authority` is matched against operations of an incoming, signed transaction. The wording *matching* refers to:
|
||||
- `operation_id` is equal to the id of the incoming operation
|
||||
- `account_id` is in the required accounts of the operation
|
||||
- the `authority` of the `custom_active_authority` is given by the signatures of the transaction
|
||||
- `now` is within `valid_to` and `valid_from`
|
||||
- all `asserts` pass positively
|
||||
- timestamp `now` is within `valid_to` and `valid_from`
|
||||
- all `restrictions` assert positively
|
||||
|
||||
### Asserts
|
||||
### Restrictions
|
||||
|
||||
The `asserts` field is a list of restrictions consisting of argument to assert mappings.
|
||||
The `restrictions` field is a list of restrictions consisting of argument to assert mappings.
|
||||
A dictionary-type object like
|
||||
```
|
||||
assert_object = {
|
||||
restriction = {
|
||||
function, // argument_identifier
|
||||
argument, // constant value, or pointer to a dynamic value (argument of the operation, or attribute when nested)
|
||||
data, // data specific to the function
|
||||
}
|
||||
```
|
||||
is called a restriction. All asserts within one restriction are evaluated per default with `AND` logic.
|
||||
is called a restriction, that can assert itself positively (passed) or negatively (violated). All restrictions are evaluated per default with `AND` logic to determine if the whole list has asserted positively.
|
||||
|
||||
List of possible asserts are:
|
||||
List of possible restrictions are:
|
||||
|
||||
| function | data | state |
|
||||
| ------------- |:-------------:| -----:|
|
||||
|
@ -96,15 +96,16 @@ List of possible asserts are:
|
|||
| `logical` | list of restrictions | stateless |
|
||||
|
||||
Following cases must hold for a restriction:
|
||||
- if there is no value given (e.g. an optional argument, or nested value not given), the assert passes (no change, no violation)
|
||||
- if the expected type of the argument does not match the given type (no implicit type conversion), assert fails
|
||||
- if the assert fails, the restriction fails
|
||||
- if there is no value given (e.g. an optional argument, or nested value not given), the restrictions is passed (no change, no violation)
|
||||
- if the expected type of the argument does not match the given type (no implicit type conversion), the restriction is violated
|
||||
- if the function of the restriction asserts negatively, the restriction is violated
|
||||
|
||||
Note:
|
||||
- If required a field can be added that stores the assumed type of the argument
|
||||
- If arguments are given by the operation that have no restriction they can have any value
|
||||
|
||||
In the following we list possible `assert_objects`. Mentioning `argument value` refers to the value of the argument of the operation specified by `argument_identifier` of a restriction. . All asserts imply: If the `argument` is given, it must pass the `assert`. If the `argument` is not given, assert is implicitly passed.
|
||||
In the following we list possible `restriction`s. Mentioning `argument value` in the text below refers to the value of
|
||||
the argument of the operation specified by `argument` of a restriction.
|
||||
|
||||
#### `any`
|
||||
Stateless assert, all argument types. `Argument value` must be equal to one of values in the data list
|
||||
|
@ -126,18 +127,18 @@ The different asserts read as:
|
|||
#### `limit`
|
||||
Statefull assert, only `int` type arguments. When the authority is created, `interval_began` is set to `valid_from` from its custom active authority and `max_cumsum` to `0`. Incoming operations are first tried to match all stateless asserts,
|
||||
and if all passes continue with statefull asserts. If `now > interval_began + interval_in_sec`, then set `max_cumsum = 0` and set `interval_began = now`.
|
||||
The assert that needs to pass is now `current_cumsum + incoming value <= max_cumsum`. If all asserts are passed, update `current_cumsum = current_cumsum + incoming value` of all involved statefull asserts.
|
||||
The assert that needs to pass is now `current_cumsum + incoming value <= max_cumsum`. If all `asserts` of this `custom_active_authority` pass, update `current_cumsum = current_cumsum + incoming value`.
|
||||
|
||||
#### `limit_monthly`
|
||||
Statefull assert, only `int` type arguments. Analogue to `limit`, but `interval_began` is initially set to `month(valid_from)` and set to `month(now)` on update, additionally the time assert is `month(now) >= interval_began + interval_in_months` (include logic for month overflow when year changes).
|
||||
|
||||
#### `attribute_assert`
|
||||
Stateless assert, only for dictionary type objects. The `attribute_to_assert` list contains restrictions that all must assert positively. Allows nesting of `attribute_assert`.
|
||||
Stateless assert, only for dictionary type objects. The data list contains restrictions that all must pass, the reference for the `argument` of the child restriction is nested into the attributes of the parent dictionary type object. Allows nesting of `attribute_assert`.
|
||||
|
||||
#### `logical`
|
||||
Stateless assert, only for dictionary type objects. The data is a list of restrictions, `argument` defines the logical link
|
||||
- `OR`: If one of the restrictions in data asserts positively
|
||||
- `AND`: If ALL restrictions in data assert positively
|
||||
- `OR`: If one of the restrictions in data passes, this restriction passes
|
||||
- `AND`: If ALL restrictions in data pass, this restriction passes
|
||||
|
||||
#### Example: Nested arguments like `options`
|
||||
Assume `asset_update_operation`. All attributes of its `options` must be filled on update call. This assert can not be used to realize a "may only change attribute xzy of `options`". This would require that the logic knows which of the arguments are reflected on-chain and it knows how to query it for every operation that contains `options`. If `options` are to be restricted with this assert, all values that should not change would need be fixated by defining an `any` assert for those attributes, while having e.g. a `lt` assert for the one attribute that is allowed to change.
|
||||
|
@ -148,7 +149,7 @@ Assume account A and B and some unrelated key K. Furthermore A has a custom acti
|
|||
custom active authority = {
|
||||
valid_from: 7.7.2018 00:00
|
||||
valid_to: 8.7.2018 00:00
|
||||
operationid: transfer,
|
||||
operation_id: transfer,
|
||||
authority: {
|
||||
threshold: 1
|
||||
key_auth: [K, 1]
|
||||
|
@ -215,7 +216,7 @@ Normal accounts can only create custom active authoritites with a duration of ma
|
|||
We propose do split the implmentation into two milestones. Each milestone will be voted on as a separate BSIP:
|
||||
|
||||
1. Implementation of basic functionaliy to allow custom active permissions and authorities, including `any`, `none` and `lt, le, gt, ge` and `attribute_assert` `asserts`. If deemed necessary by developpers, reduce to only allow one key or one account for every `custom active authority`
|
||||
2. Evaluation of stateful asserts `limit` and `limit_monthly` in terms of performance. If positively evaluated, implement
|
||||
2. Implement stateful asserts `limit` and `limit_monthly` and `logical`
|
||||
|
||||
This approach allows as well to add other asserts at a later stage (with a new BSIP).
|
||||
|
||||
|
|
Loading…
Reference in a new issue