Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions packages/protocol/src/state/AppendOnlyStateSet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import type { Bool, Field, FlexibleProvablePure } from "o1js";
import { Mixin } from "ts-mixer";

import { Path } from "../model/Path";

import { State, WithStateServiceProvider, WithPath } from "./State";

/**
* Map-like wrapper for state
*/
export class AppendOnlyStateSet<ValueType> extends Mixin(
WithPath,
WithStateServiceProvider
) {
/**
* Create a new state map with the given key and value types
*
* @param keyType - Type to be used as a key
* @param valueType - Type to be stored as a value
* @returns State map with provided key and value types.
*/
public static from<ValueType>(
valueType: FlexibleProvablePure<ValueType>
): AppendOnlyStateSet<ValueType> {
return new AppendOnlyStateSet<ValueType>(valueType);
}

public constructor(public valueType: FlexibleProvablePure<ValueType>) {
super();
}

public getPath(value: ValueType): Field {
this.hasPathOrFail();
return Path.fromKey(this.path, this.valueType, value);
}

// TODO has? includes?
public async contains(value: ValueType): Promise<Bool> {
// TODO This does a unnecessary hashing step to determine the leaf value.
// We would be fine with just storing a Bool here, but that means writing a
// custom variant of `State`
const state = State.from(this.valueType);
this.hasPathOrFail();
this.hasStateServiceOrFail();

state.path = this.getPath(value);
state.stateServiceProvider = this.stateServiceProvider;
const stateValue = await state.get();
return stateValue.isSome;
}

private async add(value: ValueType): Promise<void> {
const state = State.from(this.valueType);
this.hasPathOrFail();
this.hasStateServiceOrFail();

state.path = this.getPath(value);
state.stateServiceProvider = this.stateServiceProvider;

return await state.set(value);
}

// TODO Adding a remove would require State.delete()
}
2 changes: 1 addition & 1 deletion packages/protocol/src/state/StateMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export class StateMap<KeyType, ValueType> extends Mixin(
this.hasPathOrFail();
this.hasStateServiceOrFail();

state.path = Path.fromKey(this.path, this.keyType, key);
state.path = this.getPath(key);
state.stateServiceProvider = this.stateServiceProvider;
return await state.set(value);
}
Expand Down
Loading