Skip to content

Commit 53f3bb0

Browse files
authored
Merge pull request #1997 from o1-labs/feature/merkle-list-pop-option
Add important MerkleList method
2 parents a764fdb + ceafc4d commit 53f3bb0

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
2020
### Added
2121
- `setFee` and `setFeePerSnarkCost` for `Transaction` and `PendingTransaction` https://github.com/o1-labs/o1js/pull/1968
2222
- Doc comments for various ZkProgram methods https://github.com/o1-labs/o1js/pull/1974
23+
- `MerkleList.popOption()` for popping the last element and also learning if there was one https://github.com/o1-labs/o1js/pull/1997
2324

2425
### Changed
2526
- Sort order for actions now includes the transaction sequence number and the exact account id sequence https://github.com/o1-labs/o1js/pull/1917

src/lib/provable/merkle-list.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { provableFromClass } from './types/provable-derivers.js';
66
import { Poseidon, packToFields, ProvableHashable } from './crypto/poseidon.js';
77
import { Unconstrained } from './types/unconstrained.js';
88
import { ProvableType, WithProvable } from './types/provable-intf.js';
9+
import { Option } from './option.js';
910

1011
export {
1112
MerkleListBase,
@@ -166,6 +167,27 @@ class MerkleList<T> implements MerkleListBase<T> {
166167
return Provable.if(isEmpty, provable, provable.empty(), element);
167168
}
168169

170+
/**
171+
* Remove the last element from the list and return it as an option:
172+
* Some(element) if the list is non-empty, None if the list is empty.
173+
*
174+
* **Warning**: If the list is empty, the the option's .value is entirely unconstrained.
175+
*/
176+
popOption(): Option<T> {
177+
let { previousHash, element } = this.popWitness();
178+
let isEmpty = this.isEmpty();
179+
let emptyHash = this.Constructor.emptyHash;
180+
181+
let currentHash = this.nextHash(previousHash, element);
182+
currentHash = Provable.if(isEmpty, emptyHash, currentHash);
183+
this.hash.assertEquals(currentHash);
184+
185+
this.hash = Provable.if(isEmpty, emptyHash, previousHash);
186+
let provable = this.innerProvable;
187+
const OptionT = Option(provable);
188+
return new OptionT({ isSome: isEmpty.not(), value: element });
189+
}
190+
169191
/**
170192
* Return the last element, but only remove it if `condition` is true.
171193
*

0 commit comments

Comments
 (0)