Operations
Operations
State chain blocks contain an array of operations that modify the in-memory KV store. There are two operation types: set and delete.
#Op struct
type Op struct { Action string `json:"action"` // "set" or "delete" Key string `json:"key"` Value json.RawMessage `json:"value,omitempty"`}| Field | Description |
|---|---|
Action | Either "set" to create/update a key or "delete" to remove it |
Key | The key to operate on (see key format below) |
Value | JSON value for set operations; omitted for delete |
#Actions
#Set
Creates or updates a key with a JSON value:
{ "action": "set", "key": "sys.dao_keyset", "value": {"keys": ["aabb..."], "threshold": 2}}#Delete
Removes a key from the KV store:
{ "action": "delete", "key": "config.deprecated_param"}#Key format
Keys must match the regex ^[a-z0-9_.-]+$:
- Lowercase letters, digits, underscores, dots, and hyphens only.
- Minimum length: 1 character.
- Maximum length: 128 characters (
MaxKeyLength).
#Value constraints
| Constraint | Limit |
|---|---|
| Must be valid JSON | Checked via json.Valid() |
| Maximum size | 65,536 bytes (64 KB) |
Required for set | Cannot be empty |
#System keys
Keys prefixed with sys. have special validation rules:
| Key | Value type | Description |
|---|---|---|
sys.dao_keyset | DAOKeyset | The DAO signer quorum configuration |
sys.timekeepers | TimekeeperConfig | Trusted timekeeper keys and threshold |
#sys.dao_keyset validation
When setting sys.dao_keyset, the value must be a valid DAOKeyset:
- At least one key.
- No duplicate keys.
- Each key must be exactly 64 hex characters (32-byte ed25519 public key).
- Each key must be valid hex (not just 64 characters).
- Threshold must be >=
MinDAOThreshold(2). - Threshold must be <= number of keys.
The DAOKeyset() accessor also enforces MinDAOThreshold=2 at read time, so even a keyset written by an older version is validated on access.
#sys.timekeepers validation
When setting sys.timekeepers, the value must be a valid timekeeper config:
- At least one key.
- Each key must be exactly 64 hex characters.
- Threshold must be between 1 and the number of keys (inclusive).
#KV Store
The KVStore is an in-memory key-value store that holds the accumulated state of all applied operations.
type KVStore struct { data map[string]json.RawMessage}#Methods
| Method | Description |
|---|---|
ApplyOps(ops []Op) | Apply a batch of set/delete operations |
Get(key) (json.RawMessage, bool) | Retrieve a value by key |
GetByPrefix(prefix) map[string]json.RawMessage | Retrieve all keys matching a prefix |
GetAll() map[string]json.RawMessage | Dump the entire store |
DAOKeyset() (*DAOKeyset, error) | Parse and return the current DAO keyset from sys.dao_keyset |
#ApplyOps
Operations are applied in order. A set overwrites any existing value; a delete removes the key. There is no transaction rollback -- if a block is accepted, all its ops are applied.
func (kv *KVStore) ApplyOps(ops []Op) { for _, op := range ops { switch op.Action { case "set": kv.data[op.Key] = op.Value case "delete": delete(kv.data, op.Key) } }}#Block hash computation
The block hash is computed over the operations only, not the signatures or other metadata. This is critical because it allows DAO members to sign the same hash independently -- they agree on what the block does, not on who else has signed it.
#Common use cases
#DAO keyset rotation
Adding a new signer and increasing the threshold:
{ "ops": [ { "action": "set", "key": "sys.dao_keyset", "value": { "keys": [ "aabb11...existing1", "ccdd22...existing2", "eeff33...new_member" ], "threshold": 2 } } ]}#Timekeeper configuration
Setting up trusted timekeepers for compute lease attestations:
{ "ops": [ { "action": "set", "key": "sys.timekeepers", "value": { "keys": [ "1122...timekeeper_a", "3344...timekeeper_b", "5566...timekeeper_c" ], "threshold": 2 } } ]}#Arbitrary configuration
The KV store can hold any governance-related data:
{ "ops": [ {"action": "set", "key": "config.emission_rate", "value": 100}, {"action": "set", "key": "config.max_lease_days", "value": 365}, {"action": "delete", "key": "config.deprecated_flag"} ]}#Op validation
Every operation in a block is validated before the block is accepted:
| Check | Rule |
|---|---|
| Key format | Must match ^[a-z0-9_.-]+$ |
| Key length | 1 to 128 characters |
| Set value present | set ops must have a non-empty value |
| Set value size | Value must be <= 65,536 bytes |
| Set value JSON | Value must be valid JSON |
| System key rules | sys.* keys have additional schema validation |
| Delete system keys | sys.* keys cannot be deleted |
| Block has ops | Block must contain at least one operation |