Skip to content

Commit 6e075ab

Browse files
committed
made the "op" parameter optional in Authorizer.attempt(op?): if it's missing, it means that the caller just wants to know if the authorization would go through, but without actually doing anything. Then added CausalSet.canAdd, CausalSet.canDelete, CausalArray.canInsert, CausalArray.canDelete using that.
1 parent c39b3fe commit 6e075ab

File tree

4 files changed

+64
-57
lines changed

4 files changed

+64
-57
lines changed

src/data/collections/causal/CausalArray.ts

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,14 @@ class CausalArray<T> extends BaseCausalCollection<T> implements CausalCollection
197197
this._ordinals = [];
198198
}
199199

200+
canInsert(author?: Identity, extraAuth?: Authorizer): Promise<boolean> {
201+
return Authorization.chain(this.createInsertAuthorizer(author), extraAuth).attempt();
202+
}
203+
204+
canDelete(author?: Identity, extraAuth?: Authorizer): Promise<boolean> {
205+
return Authorization.chain(this.createDeleteAuthorizer(author), extraAuth).attempt();
206+
}
207+
200208
async insertAt(element: T, idx: number, author?: Identity, extraAuth?: Authorizer): Promise<boolean> {
201209
return this.insertManyAt([element], idx, author, extraAuth);
202210
}
@@ -259,7 +267,7 @@ class CausalArray<T> extends BaseCausalCollection<T> implements CausalCollection
259267
CausalCollectionOp.setSingleAuthorIfNecessary(insertOp);
260268
}
261269

262-
const auth = Authorization.chain(this.createInsertAuthorizer(element, insertOp.getAuthor()), extraAuth);
270+
const auth = Authorization.chain(this.createInsertAuthorizer(insertOp.getAuthor()), extraAuth);
263271

264272
this.setCurrentPrevOpsTo(insertOp);
265273

@@ -416,7 +424,7 @@ class CausalArray<T> extends BaseCausalCollection<T> implements CausalCollection
416424
CausalCollectionOp.setSingleAuthorIfNecessary(deleteOp);
417425
}
418426

419-
const auth = Authorization.chain(this.createDeleteAuthorizer(insertOp.element as T, deleteOp.getAuthor()), extraAuth);
427+
const auth = Authorization.chain(this.createDeleteAuthorizer(deleteOp.getAuthor()), extraAuth);
420428

421429
this.setCurrentPrevOpsTo(deleteOp);
422430

@@ -612,10 +620,9 @@ class CausalArray<T> extends BaseCausalCollection<T> implements CausalCollection
612620
const author = op.getAuthor();
613621

614622
const auth = (op instanceof InsertOp) ?
615-
this.createInsertAuthorizer(op.element, author)
623+
this.createInsertAuthorizer(author)
616624
:
617-
this.createDeleteAuthorizerByHash(
618-
HashedObject.hashElement(op.getInsertOp().element), author);
625+
this.createDeleteAuthorizer(author);
619626

620627
const usedKeys = new Set<string>();
621628

@@ -643,25 +650,28 @@ class CausalArray<T> extends BaseCausalCollection<T> implements CausalCollection
643650
return 'CausalArray/attest-member:' + hash + '-belongs-to-' + this.hash();
644651
}
645652

646-
async attestMembershipForOp(elmt: T, op: MutationOp): Promise<boolean> {
653+
async attestMembershipForOp(elmt: T, op?: MutationOp): Promise<boolean> {
647654

648655
const hash = HashedObject.hashElement(elmt);
649656

650657
return this.attestMembershipForOpByHash(hash, op);
651658
}
652659

653-
async attestMembershipForOpByHash(hash: Hash, op: MutationOp): Promise<boolean> {
660+
async attestMembershipForOpByHash(hash: Hash, op?: MutationOp): Promise<boolean> {
654661

655662
const insertOps = this._currentInsertOps.get(hash);
656663

657664
if (insertOps.size > 0) {
658-
const insertOp = insertOps.values().next().value as InsertOp<T>;
659665

660-
const attestOp = new MembershipAttestationOp(insertOp, op);
666+
if (op !== undefined) {
667+
const insertOp = insertOps.values().next().value as InsertOp<T>;
661668

662-
await this.applyNewOp(attestOp);
663-
const key = this.attestationKeyByHash(hash);
664-
op.addCausalOp(key, attestOp);
669+
const attestOp = new MembershipAttestationOp(insertOp, op);
670+
671+
await this.applyNewOp(attestOp);
672+
const key = this.attestationKeyByHash(hash);
673+
op.addCausalOp(key, attestOp);
674+
}
665675

666676
return true;
667677
} else {
@@ -711,26 +721,17 @@ class CausalArray<T> extends BaseCausalCollection<T> implements CausalCollection
711721
createMembershipAuthorizer(elmt: T): Authorizer {
712722

713723
return {
714-
attempt : (op: MutationOp) => this.attestMembershipForOp(elmt, op),
724+
attempt : (op?: MutationOp) => this.attestMembershipForOp(elmt, op),
715725
verify : (op: MutationOp, usedKeys: Set<string>) => this.verifyMembershipAttestationForOp(elmt, op, usedKeys)
716726
};
717727

718728
}
719729

720-
protected createInsertAuthorizer(elmt: T, author?: Identity): Authorizer {
721-
722-
if (!this.shouldAcceptElement(elmt)) {
723-
return Authorization.never;
724-
} else {
725-
return this.createWriteAuthorizer(author);
726-
}
727-
}
728-
729-
protected createDeleteAuthorizer(elmt: T, author?: Identity): Authorizer {
730-
return this.createDeleteAuthorizerByHash(HashedObject.hashElement(elmt), author);
730+
protected createInsertAuthorizer(author?: Identity): Authorizer {
731+
return this.createWriteAuthorizer(author);
731732
}
732733

733-
protected createDeleteAuthorizerByHash(_elmtHash: Hash, author?: Identity): Authorizer {
734+
protected createDeleteAuthorizer(author?: Identity): Authorizer {
734735
return this.createWriteAuthorizer(author);
735736
}
736737

src/data/collections/causal/CausalSet.ts

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,15 @@ class CausalSet<T> extends BaseCausalCollection<T> implements CausalCollection<T
211211
return CausalSet.className;
212212
}
213213

214+
canAdd(author?: Identity, extraAuth?: Authorizer): Promise<boolean> {
215+
return Authorization.chain(this.createAddAuthorizer(author), extraAuth).attempt();
216+
}
217+
218+
canDelete(author?: Identity, extraAuth?: Authorizer): Promise<boolean> {
219+
return Authorization.chain(this.createDeleteAuthorizer(author), extraAuth).attempt();
220+
}
221+
222+
214223
async add(elmt: T, author?: Identity, extraAuth?: Authorizer): Promise<boolean> {
215224

216225
if (!(elmt instanceof HashedObject) && !HashedObject.isLiteral(elmt)) {
@@ -229,7 +238,7 @@ class CausalSet<T> extends BaseCausalCollection<T> implements CausalCollection<T
229238
CausalCollectionOp.setSingleAuthorIfNecessary(addOp);
230239
}
231240

232-
const auth = Authorization.chain(this.createAddAuthorizer(elmt, addOp.getAuthor()), extraAuth);
241+
const auth = Authorization.chain(this.createAddAuthorizer(addOp.getAuthor()), extraAuth);
233242

234243
this.setCurrentPrevOpsTo(addOp);
235244

@@ -246,7 +255,6 @@ class CausalSet<T> extends BaseCausalCollection<T> implements CausalCollection<T
246255
const hash = HashedObject.hashElement(elmt);
247256

248257
return this.deleteByHash(hash, author, extraAuth);
249-
250258
}
251259

252260
async deleteByHash(hash: Hash, author?: Identity, extraAuth?: Authorizer): Promise<boolean> {
@@ -263,7 +271,7 @@ class CausalSet<T> extends BaseCausalCollection<T> implements CausalCollection<T
263271
CausalCollectionOp.setSingleAuthorIfNecessary(deleteOp);
264272
}
265273

266-
const auth = Authorization.chain(this.createDeleteAuthorizerByHash(hash, deleteOp.getAuthor()), extraAuth);
274+
const auth = Authorization.chain(this.createDeleteAuthorizer(deleteOp.getAuthor()), extraAuth);
267275

268276
this.setCurrentPrevOpsTo(deleteOp);
269277

@@ -309,27 +317,30 @@ class CausalSet<T> extends BaseCausalCollection<T> implements CausalCollection<T
309317
return 'CausalSet/attest:' + hash + '-belongs-to-' + this.hash();
310318
}
311319

312-
async attestMembershipForOp(elmt: T, op: MutationOp): Promise<boolean> {
320+
async attestMembershipForOp(elmt: T, op?: MutationOp): Promise<boolean> {
313321

314322
const hash = HashedObject.hashElement(elmt);
315323

316324
return this.attestMembershipForOpByHash(hash, op);
317325
}
318326

319-
async attestMembershipForOpByHash(hash: Hash, op: MutationOp): Promise<boolean> {
327+
async attestMembershipForOpByHash(hash: Hash, op?: MutationOp): Promise<boolean> {
320328

321329
const addOpHashes = this._currentAddOpsPerElmt.get(hash);
322330

323331
if (addOpHashes.size > 0) {
324-
const addOpHash = addOpHashes.values().next().value as Hash;
325-
const addOp = this._currentAddOps.get(addOpHash) as AddOp<T>;
326332

327-
const attestOp = new MembershipAttestationOp(addOp, op);
333+
if (op !== undefined) {
334+
const addOpHash = addOpHashes.values().next().value as Hash;
335+
const addOp = this._currentAddOps.get(addOpHash) as AddOp<T>;
328336

329-
await this.applyNewOp(attestOp);
330-
const key = this.attestationKeyByHash(hash);
331-
op.addCausalOp(key, attestOp);
337+
const attestOp = new MembershipAttestationOp(addOp, op);
332338

339+
await this.applyNewOp(attestOp);
340+
const key = this.attestationKeyByHash(hash);
341+
op.addCausalOp(key, attestOp);
342+
}
343+
333344
return true;
334345
} else {
335346
return false;
@@ -389,10 +400,9 @@ class CausalSet<T> extends BaseCausalCollection<T> implements CausalCollection<T
389400
const author = op.getAuthor();
390401

391402
const auth = (op instanceof AddOp) ?
392-
this.createAddAuthorizer(op.getElement(), author)
403+
this.createAddAuthorizer(author)
393404
:
394-
this.createDeleteAuthorizerByHash(
395-
HashedObject.hashElement(op.getAddOp().getElement()), author);;
405+
this.createDeleteAuthorizer(author);;
396406

397407
const usedKeys = new Set<string>();
398408

@@ -532,22 +542,18 @@ class CausalSet<T> extends BaseCausalCollection<T> implements CausalCollection<T
532542
return found;
533543
}
534544

535-
protected createAddAuthorizer(_elmt: T, author?: Identity): Authorizer {
545+
protected createAddAuthorizer(author?: Identity): Authorizer {
536546
return this.createWriteAuthorizer(author);
537547
}
538548

539-
protected createDeleteAuthorizer(elmt: T, author?: Identity): Authorizer {
540-
return this.createDeleteAuthorizerByHash(HashedObject.hashElement(elmt), author);
541-
}
542-
543-
protected createDeleteAuthorizerByHash(_elmtHash: Hash, author?: Identity): Authorizer {
549+
protected createDeleteAuthorizer(author?: Identity): Authorizer {
544550
return this.createWriteAuthorizer(author);
545551
}
546552

547553
createMembershipAuthorizer(elmt: T): Authorizer {
548554

549555
return {
550-
attempt : (op: MutationOp) => this.attestMembershipForOp(elmt, op),
556+
attempt : (op?: MutationOp) => this.attestMembershipForOp(elmt, op),
551557
verify : (op: MutationOp, usedKeys: Set<string>) => this.verifyMembershipAttestationForOp(elmt, op, usedKeys)
552558
};
553559

src/data/collections/causal/SingleAuthorCausalSet.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class SingleAuthorCausalSet<T> extends CausalSet<T> {
5858
return this.getAuthor() !== undefined;
5959
}
6060

61-
protected createAddAuthorizer(_elmt: T, author: Identity): Authorizer {
61+
protected createAddAuthorizer(author: Identity): Authorizer {
6262

6363
if (author.equals(this.getAuthor())) {
6464
return Authorization.always;

src/data/model/causal/Authorization.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,22 +39,22 @@ import { MutationOp } from '../mutable/MutationOp';
3939
* _exactly_ the provided keys.
4040
*/
4141

42-
type Attestator = (op: MutationOp) => Promise<boolean>;
42+
type Attestator = (op?: MutationOp) => Promise<boolean>;
4343

4444
class Attestation {
45-
static always : Attestator = (_op: MutationOp) => Promise.resolve(true);
46-
static never : Attestator = (_op: MutationOp) => Promise.resolve(false);
45+
static always : Attestator = (_op?: MutationOp) => Promise.resolve(true);
46+
static never : Attestator = (_op?: MutationOp) => Promise.resolve(false);
4747
static chain : (a1: Attestator, a2?: Attestator) => Attestator
4848

4949
= (a1: Attestator, a2?: Attestator) =>
50-
( async (op: MutationOp) => {
50+
( async (op?: MutationOp) => {
5151

52-
const savedCausalOps = new HashedMap(op.getCausalOps().entries());
52+
const savedCausalOps = new HashedMap(op?.getCausalOps().entries());
5353

5454
if (await a1(op) && (a2 === undefined || await a2(op))) {
5555
return true;
5656
} else {
57-
op.setCausalOps(savedCausalOps.entries())
57+
op?.setCausalOps(savedCausalOps.entries())
5858
return false;
5959
}
6060
}
@@ -64,7 +64,7 @@ class Attestation {
6464
static oneOf : (candidates: Array<Attestator>) => Attestator
6565

6666
= (candidates: Array<Attestator|undefined>) => (
67-
async (op: MutationOp) => {
67+
async (op?: MutationOp) => {
6868
for (const candidate of candidates) {
6969
if (candidate !== undefined && await candidate(op)) {
7070
return true;
@@ -76,13 +76,13 @@ class Attestation {
7676
static all : (authorizers: Array<Attestator>) => Attestator
7777

7878
= (authorizers: Array<Attestator>) =>
79-
async (op: MutationOp) => {
79+
async (op?: MutationOp) => {
8080

81-
const savedCausalOps = new HashedMap(op.getCausalOps().entries());
81+
const savedCausalOps = new HashedMap(op?.getCausalOps().entries());
8282

8383
for (const authorize of authorizers) {
8484
if (!(await authorize(op))) {
85-
op.setCausalOps(savedCausalOps.entries());
85+
op?.setCausalOps(savedCausalOps.entries());
8686
return false;
8787
}
8888
}

0 commit comments

Comments
 (0)