/**
* This module provides an API for aggregatable integers that allow addition,
* subtraction, and reading.
*
* Design rationale (V1)
* =====================
* Aggregator can be seen as a parellizable integer that supports addition,
* subtraction and reading. The first version (V1) of aggregator has the
* the following specification.
*
* add(value: u128)
* Speculatively adds a `value` to aggregator. This is a cheap operation
* which is easly parallelizable. If the result of addition overflows a
* `limit` (one of aggregator's fields), an error is produced and the
* execution aborts.
*
* sub(value: u128)
* Subtracts a `value` from aggregator. This is an expensive operation
* which is non-parallelizable. It reads the value of the aggregator, and
* the tries to subtract. If the result goes below zero, an error is produced
* and the execution aborts.
*
* read(): u128
* Reads (materializes) the value of an aggregator. This is an expensive
* operation which usually involves reading from the storage.
*
* destroy()
* Destriys and aggregator, also cleaning up storage if necessary.
*
* Note that there is no constructor in `Aggregator` API. This is done on purpose.
* For every aggregator, we need to know where its value is stored on chain.
* Currently, Move does not allow fine grained access to struct fields. For
* example, given a struct
*
* struct Foo has key {
* a: A,
* b: u128,
* }
*
* there is no way of getting a value of `Foo::a` without hardcoding the layout
* of `Foo` and the field offset. To mitigate this problem, one can use a table.
* Every item stored in the table is uniqely identified by (handle, key) pair:
* `handle` identifies a table instance, `key` identifies an item within the table.
*
* So how is this related to aggregator? Well, aggregator can reuse the table's
* approach for fine-grained storage. However, since native functions only see a
* reference to aggregator, we must ensure that both `handle` and `key` are
* included as fields. Therefore, the struct looks like
*
* struct Aggregator {
* handle: u128,
* key: u128,
* ..
* }
*
* Remaining question is how to generate this (handle, key) pair. For that, we have
* a dedicated struct called `AggregatorFactory` which is responsible for constructing
* aggregators. See `aggregator_factory.move` for more details.
*
* Advice to users (V1)
* ====================
* Users are encouraged to use "cheap" operations (e.g. additions) to exploit the
* parallelism in execution.
*
* **Module ID:** `0x1::aggregator`
*
* @module
*/
import type * as p from "@movingco/prelude";
/** Type name: `0x1::aggregator::Aggregator` */
export interface IAggregator {
handle: p.U128;
key: p.U128;
limit: p.U128;
}
export { idl } from "./idl.js";
/** The address of the module. */
export const ADDRESS = "0x1" as const;
/** The full module name. */
export const FULL_NAME = "0x1::aggregator" as const;
/** The name of the module. */
export const NAME = "aggregator" as const;
/** Module ID information. */
export const id = {
ADDRESS,
FULL_NAME,
NAME,
} as const;
export * as errors from "./errors.js";
/** Module error codes. */
export const errorCodes = {
"1": {
name: "EAGGREGATOR_OVERFLOW",
doc: "When the value of aggregator (actual or accumulated) overflows (raised\nby native code).",
},
"2": {
name: "EAGGREGATOR_UNDERFLOW",
doc: "When the value of aggregator (actual or accumulated) underflows, i.e goes\nbelow zero (raised by native code).",
},
"3": {
name: "ENOT_SUPPORTED",
doc: "When aggregator feature is not supported (raised by native code).",
},
} as const;
/** All module function IDLs. */
export const functions = {} as const;
/** All struct types with ability `key`. */
export const resources = {} as const;
/** All struct types. */
export const structs = {
Aggregator: "0x1::aggregator::Aggregator",
} as const;
/** Payload generators for module `0x1::aggregator`. */
const moduleImpl = {
...id,
errorCodes,
functions,
resources,
structs,
} as const;
/**
* This module provides an API for aggregatable integers that allow addition,
* subtraction, and reading.
*
* Design rationale (V1)
* =====================
* Aggregator can be seen as a parellizable integer that supports addition,
* subtraction and reading. The first version (V1) of aggregator has the
* the following specification.
*
* add(value: u128)
* Speculatively adds a `value` to aggregator. This is a cheap operation
* which is easly parallelizable. If the result of addition overflows a
* `limit` (one of aggregator's fields), an error is produced and the
* execution aborts.
*
* sub(value: u128)
* Subtracts a `value` from aggregator. This is an expensive operation
* which is non-parallelizable. It reads the value of the aggregator, and
* the tries to subtract. If the result goes below zero, an error is produced
* and the execution aborts.
*
* read(): u128
* Reads (materializes) the value of an aggregator. This is an expensive
* operation which usually involves reading from the storage.
*
* destroy()
* Destriys and aggregator, also cleaning up storage if necessary.
*
* Note that there is no constructor in `Aggregator` API. This is done on purpose.
* For every aggregator, we need to know where its value is stored on chain.
* Currently, Move does not allow fine grained access to struct fields. For
* example, given a struct
*
* struct Foo has key {
* a: A,
* b: u128,
* }
*
* there is no way of getting a value of `Foo::a` without hardcoding the layout
* of `Foo` and the field offset. To mitigate this problem, one can use a table.
* Every item stored in the table is uniqely identified by (handle, key) pair:
* `handle` identifies a table instance, `key` identifies an item within the table.
*
* So how is this related to aggregator? Well, aggregator can reuse the table's
* approach for fine-grained storage. However, since native functions only see a
* reference to aggregator, we must ensure that both `handle` and `key` are
* included as fields. Therefore, the struct looks like
*
* struct Aggregator {
* handle: u128,
* key: u128,
* ..
* }
*
* Remaining question is how to generate this (handle, key) pair. For that, we have
* a dedicated struct called `AggregatorFactory` which is responsible for constructing
* aggregators. See `aggregator_factory.move` for more details.
*
* Advice to users (V1)
* ====================
* Users are encouraged to use "cheap" operations (e.g. additions) to exploit the
* parallelism in execution.
*/
export const moduleDefinition = moduleImpl as p.MoveModuleDefinition<
"0x1",
"aggregator"
> as typeof moduleImpl;