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
|
# 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
|
# 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
|
### 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 = {
|
custom_active_permission = {
|
||||||
account_id, // account that is assigned to this 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 = {
|
custom_active_authority = {
|
||||||
valid_from, // timestamp when this is active, defaults to now
|
valid_from, // timestamp when this is active, defaults to now
|
||||||
valid_to, // timestamp when this is invalid, defaults to 1 year
|
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),
|
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.
|
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:
|
A `custom active authority` is matched against operations of an incoming, signed transaction. The wording *matching* refers to:
|
||||||
- `operationid` is equal to the id of the incoming operation
|
- `operation_id` is equal to the id of the incoming operation
|
||||||
- assigned account of parent `custom active permission` is in the required accounts of the 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
|
- the `authority` of the `custom_active_authority` is given by the signatures of the transaction
|
||||||
- `now` is within `valid_to` and `valid_from`
|
- timestamp `now` is within `valid_to` and `valid_from`
|
||||||
- all `asserts` pass positively
|
- 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
|
A dictionary-type object like
|
||||||
```
|
```
|
||||||
assert_object = {
|
restriction = {
|
||||||
function, // argument_identifier
|
function, // argument_identifier
|
||||||
argument, // constant value, or pointer to a dynamic value (argument of the operation, or attribute when nested)
|
argument, // constant value, or pointer to a dynamic value (argument of the operation, or attribute when nested)
|
||||||
data, // data specific to the function
|
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 |
|
| function | data | state |
|
||||||
| ------------- |:-------------:| -----:|
|
| ------------- |:-------------:| -----:|
|
||||||
|
@ -96,15 +96,16 @@ List of possible asserts are:
|
||||||
| `logical` | list of restrictions | stateless |
|
| `logical` | list of restrictions | stateless |
|
||||||
|
|
||||||
Following cases must hold for a restriction:
|
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 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), assert fails
|
- if the expected type of the argument does not match the given type (no implicit type conversion), the restriction is violated
|
||||||
- if the assert fails, the restriction fails
|
- if the function of the restriction asserts negatively, the restriction is violated
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
- If required a field can be added that stores the assumed type of the argument
|
- 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
|
- 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`
|
#### `any`
|
||||||
Stateless assert, all argument types. `Argument value` must be equal to one of values in the data list
|
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`
|
#### `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,
|
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`.
|
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`
|
#### `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).
|
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`
|
#### `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`
|
#### `logical`
|
||||||
Stateless assert, only for dictionary type objects. The data is a list of restrictions, `argument` defines the logical link
|
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
|
- `OR`: If one of the restrictions in data passes, this restriction passes
|
||||||
- `AND`: If ALL restrictions in data assert positively
|
- `AND`: If ALL restrictions in data pass, this restriction passes
|
||||||
|
|
||||||
#### Example: Nested arguments like `options`
|
#### 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.
|
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 = {
|
custom active authority = {
|
||||||
valid_from: 7.7.2018 00:00
|
valid_from: 7.7.2018 00:00
|
||||||
valid_to: 8.7.2018 00:00
|
valid_to: 8.7.2018 00:00
|
||||||
operationid: transfer,
|
operation_id: transfer,
|
||||||
authority: {
|
authority: {
|
||||||
threshold: 1
|
threshold: 1
|
||||||
key_auth: [K, 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:
|
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`
|
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).
|
This approach allows as well to add other asserts at a later stage (with a new BSIP).
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue