From 189ceec7b177d2d5f321396ba59bbf2ac95dfcbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Schie=C3=9Fl?= Date: Fri, 27 Jul 2018 15:54:30 +0200 Subject: [PATCH] Update bsip-0040.md --- bsip-0040.md | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/bsip-0040.md b/bsip-0040.md index b9fd811..0a6869d 100644 --- a/bsip-0040.md +++ b/bsip-0040.md @@ -43,6 +43,8 @@ The description here is more on a superficial level and no recommendation how it 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 a signed transaction arrives at the backend iterate the required accounts for each operations. If they have any one custom active authority that matches the given operation, signature and passes all asserts of the custom active authority, then the active authority of the required account is granted. This search can be stopped after finding one match. +### Custom active permission + A `custom_active_permission` looks like follows (in JSON for clarification, backend serializes and stores in a different way): ``` custom_active_permission = list of custom_active_authority items @@ -56,6 +58,8 @@ custom_active_authority = { ``` Note: This assumes `custom_active_permission` is stored within `account_object`. Actual implementation details left to the implementer. +### Possible asserts + The `asserts` is a list of `assert_objects` that are all together evaluated with `and` logic to evaluate a match ``` asserts = list of assert_object @@ -73,12 +77,29 @@ List of possible asserts are: | `any` | [`list`, `of`, `allowed`, `values`] | stateless | | `range` | [`min`, `max`] | stateless | | `length` | [`min`, `max`] | stateless | -| `limit` | [`value`, `interval_in_sec`] | [`current_cumsum`, `interval_began`] | -| `limit_monthly` | [`value`, `interval_in_months`] | [`current_cumsum`, `interval_began`] | +| `limit` | [`max_cumsum`, `interval_in_sec`] | [`current_cumsum`, `interval_began`] | +| `limit_monthly` | [`max_cumsum`, `interval_in_months`] | [`current_cumsum`, `interval_began`] | -All asserts apply to `int`, `string` and `object_ids`. There is no type converstion, incompatible type means assert failure. Any more sophisticated data types are not included yet. The `length` assert is specific to `string`, whereas `range`, `limit` and `limit_monthly` is only applicable to `int`. +All asserts apply to `int`, `string` and `object_ids`. There is no type converstion, incompatible type means assert failure. Any more sophisticated data types are not included yet. -Example A: +#### `any` +Stateless assert, all argument types. Value of argument must be equal to one of values in the list + +#### `range` +Stateless assert, only `int` type arguments. Value must be inbetween `min` and `max`, inclusive. One of the bounds can be empty to indicate unlimited. + +#### `length` +Stateless assert, only `string` type arguments. Length of string (or encrypted string in case of memo) must be within `min` and `max`, inclusive. One of the bounds can be empty to indicate unlimited. + +#### `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`. +The assert that needs to pass is now `current_cumsum + incoming value <= max_cumsum`. If all asserts are passed, update `current_cumsum` of all involved statefull asserts. + +#### `limit_monthly` +Statefull assert, only `int` type arguments. Analogue to `limit`, but the time assert is `month(now) >= interval_began + interval_in_months` (include logic for month overflow when year changes). + +### Simple Example Assume account A and B and some unrelated key K. Furthermore A has a custom active authority in the following way: ``` custom active authority = {