Update bsip-0040.md

bsip53
Stefan Schießl 2018-07-30 15:00:51 +02:00 committed by GitHub
parent cf72eaa2d7
commit f0d16bb517
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 26 additions and 25 deletions

View File

@ -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).